游曠吉吉,董自鵬,顧苗苗
(蘇州市職業大學 計算機工程學院,江蘇 蘇州 215104)
水是生命的源泉,隨著經濟社會的快速發展和社會文明的進步,人類對水資源的重視程度越來越高。傳統的人工抽樣檢測水質既費時又費力,實現對水質的實時監測,無論是對保護水資源還是促進水產養殖都具有十分重要的意義[1]。
基于嵌入式的產品開發,市場廣泛、功能擴展性好[2]。本文基于STM32設計的水質監測系統,可實現對被監測水域的水溫和濁度自動實時監測并預警。
本系統以正點原子戰艦STM32F1 V3開發板作為控制器[3],總體設計采用STM32F103ZET6作為主控芯片[4],選用DS18B20溫度模塊和TSW-30濁度模塊作為傳感器[5],通過引腳設定和必要的外部電路連接,分別測量監測水域的水溫和濁度,經過信號處理和A/D轉換,將測量得到的數值顯示在TFTLCD液晶屏上,當測量值超過設定的閾值時,蜂鳴器報警,提醒現場工作人員,如圖1所示。

圖1 總體設計
本系統以STM32F103ZET6作為主控芯片,該芯片是意法半導體公司生產的一款32位Cortex-M3內核的處理器[6],具有64 kB SRAM,512 kB FLASH、最高72 MHz的工作頻率,共有112個通用IO口,是一款低功耗、高性能的芯片。該芯片已在工程上被廣泛使用,很適合本系統的嵌入式開發。
DS18B20是由DALLAS半導體公司推出的一款“一線總線”接口的溫度傳感器,具有體積小、抗干擾性強、與微處理器接口簡單的優點,測量溫度范圍-55~125 ℃,精度為±0.5 ℃,可在3.3~5.0 V的電壓范圍工作。使用時將DS18B20的平面部分朝內、曲面部分朝外,按照電源線、DQ線、接地線的次序從左到右插入開發板U6的1、2和3腳,測量結果即會以9~12位數字量方式串行傳送,不需要再外接外圍元件。
濁度傳感器通過測量水中懸浮固體總量(TSS)的變化來測量水中懸浮顆粒物的光透過率和散射率,利用光來檢測懸浮顆粒物。傳感器默認采用模擬信號的輸出模式,濁度越高輸出值越低,根據參考資料,輸出的電壓值和濁度關系,如圖2所示。在使用時電源線接開發板的5 V引腳,接地線接開發板的GND引腳,OUT接開發板的PA1引腳即可讀取到內部ADC值,通過單片機的A/D轉換即可得到電壓值,進而得到當前水的濁度。

圖2 電壓與濁度關系
軟件部分使用C語言庫函數編寫,用MDK5軟件進行編譯,用FlyMcu軟件將編譯好的.hex文件下載到STM32中,查看運行效果。主要的函數模塊有DS18B20溫度模塊、濁度模塊和主函數模塊,程序控制流程,如圖3所示。

圖3 程序控制流程
DS18B20的典型溫度讀取過程為:復位→發SKIP ROM命令(0XCC)→發開始轉換命令(0X44)→延時→復位→發送SKIP ROM命令(0XCC)→發讀存儲器命令(0XBE)→連續讀出兩個字節數據(即溫度)→結束。轉化后得到的12位數據存儲在DS18B20的兩個8比特的RAM中,如圖4所示。二進制中的前面5位是符號位,如果測得的溫度大于0,這5位為0,只要將測到的數值乘以0.062 5即可得到實際溫度;如果溫度小于0,這5位為1,測得的數值需要取反加1再乘以0.062 5即可得到實際溫度。

圖4 DS18B20數據位表示
if(TH>7)
{
TH=~TH;
TL=~TL;
temp=0; //溫度為負
}else temp=1; //溫度為正
tem=TH; //獲得高八位
tem<<=8;
tem+=TL; //獲得低八位
tem=(float)tem*0.625; //轉換
if(temp)return tem; //返回溫度值
else return -tem;
代碼實現如上所示,先判定溫度的正負,如果為負,則將高低位的值都取反,反之則數據位保持不變動,再將測量得到的數值乘以0.625,將實際溫度擴大10倍,輸出時再分別除以10取整以及取余作為整數部分和小數部分,小數點前后的數據分開輸出,并精確到0.1 ℃。
在獲取ADC的值時,因為是個實時變化的量,可能誤差較大,因此采用一定時間內多次測量取平均值的方法,獲得adcx的值,提高精確度。代碼實現如下所示。
u16 Get_Adc_Average(u8 ch,u8 times)
{
u32 temp_val=0;
u8 t;
for(t=0;t { temp_val= temp_val +Get_Adc(ch); delay_ms(5); } return temp_val/times; } adcx=Get_Adc_Average(ADC_Channel_1,10);//采樣10次 因為STM32的ADC是12位逐次逼近型的模擬數字轉換器,其值為0~4 095,定義一臨時變量temp,用于儲存測量得到的adcx值轉換為0~4.5 V的電壓值。當temp小于2.64時,直接輸出NTU的值3 000(表示水極度渾濁);當temp大于4.2時,直接輸出NTU的值0(表示水比較清澈);當temp介于2.64~4.20之間時,根據公式-1 120.4*temp*temp+5 742.3*temp-4 352.9,求得NTU的值。代碼實現如下所示。 temp=(float)adcx*(4.5/4096); if(temp<2.64) NTU=3000; else if(temp>4.2) NTU=0; else NTU=-1120.4*temp*temp+5742.3*temp-4352.9; 主函數主要包括定義一定的變量,完成延時函數初始化、設置中斷優先級、串口初始化、LED端口初始化、蜂鳴器初始化、LCD顯示屏初始化、STM32內部ADC初始化、DS18B20初始化和中文字庫初始化等。 if(t%10==0) //每100ms讀取一次 { temperature=DS18B20_Get_Temp(); if(temperature<0) { LCD_ShowChar(30+40,210,'-',16,0); //顯示負號 temperature=-temperature; //將負數轉為正數 }else LCD_ShowChar(30+40,210,' ',16,0); //原負號的位置不顯示 LCD_ShowNum(30+40+8,210,temperature/10,2,16); //顯示整數部分 LCD_ShowNum(30+40+32,210,temperature%10,1,16); //顯示小數部分 } delay_ms(10); t++; if(t==20) { t=0; } 通過t的計數和延時,每100 ms獲取一次DS18B20測得的temperature并進行判定,如果小于0,就顯示“-”號并將值取反,否則就顯示空白,然后將temperature分別除以10取整以及取余作為整數部分和小數部分輸出在屏幕上。 系統通電后,將傳感器放入水中,即可在TFTLCD液晶屏上正常顯示采集到的數據。分別選取一定程度的渾濁水和清澈水,模擬測試圖,如圖5和6所示:渾濁水測試結果NTU的值為2 407,水溫為20.1 ℃;清澈水測試結果NTU的值為0,水溫為20.5 ℃。系統設定:當水溫值低于10 ℃或高于30 ℃、濁度值高于2 800時,蜂鳴器報警。 圖5 渾濁水測試 圖6 清澈水測試 本系統在設計和實現的過程中僅加入了單一的溫度和濁度傳感器,具有投入小、適用范圍廣的優勢。但當被監測的水域面積足夠大時,可能無法客觀地反映整體水域的水質情況,并且不同深度的水質情況也會存在差異,可利用STM32良好的功能擴展性,通過多布局傳感器節點、統一收集數據管理分析的方式,更為全面地反映整體水域的水質情況。后期還可添加溶氧、酸堿度、電導率、氨氮、亞硝酸鹽pH等傳感器,多參數更為科學地、綜合地評價水質情況;還可添加LoRa無線傳輸模塊和GPRS通信模塊,通過無線傳輸的方式將數據傳送至遠端計算機保存,實現遠程實時監測。3.3 主函數模塊
4 系統測試


5 結語