OneNET麒麟座應用開發之十:空氣質量數據監測站項目總結
大氣質量數據監測站用於測試空氣質量監測及數據采集,實現野外或者室內空氣質量的檢測。
1、項目概述
本項目是一個定制項目,要求采集大氣的壓力、溫度、濕度、PM25、位置等數據並上傳到指定的後臺服務器。但有時候因為沒有條件或因為各種原因不能聯網,則采用本地保存的方式,本地保存我們決定使用SD卡來實現。除此外,為了實現顯式需求,還需要配套一些東西來實現飲食的需求,如實時時鐘記錄,上傳聯網方式的選擇等。
2、硬件設計
本項目涉及到的硬件並不復雜,我們對其中幾個實用比較多的電路做一個說明。首先說一下串口通訊電路,在本項目中激光PM25傳感器、氣體質量流量控制器、SD讀卡器等都是使用串口來實現通訊,所以我們采用如下的串口電路設計:
該方式即可支持RS232,也可實現RS485,當然簡單的TTL也沒問題,只需要根據自己的不同需求焊接不同的元器件就可實現。
接下來我們說一說PWM控制電路,其實用的是計時器來實現,由於點擊需要12V-24V的電源,所以我們外加一部分電路來實現電機的驅動,而PWM信號則有MCU產生,並能夠通過電路提升電壓。
最後我們說一下聯網部分,聯網有多種方式,有線連接、wifi連接都支持,首先說一說wifi,我們使用了ESP8266來實現這一需求,之所以選擇ESP8266是因為軟硬件實現都比較簡單,而且我們對通訊的要求並不十分高,因為10m秒鐘記錄一個數據就好了,所以成本就是主要理由了。
至於有線我們使用W5500來實現,在以前的文章中已經多次說明過,這一次就不再重復了。
3、軟件設計
接下來我們說一說軟件的設計,軟件的設計較硬件要繁雜的多,我們選取其中一部分前面沒有說明過的做一些說明。首先我們說一下PWM控制,每臺采集站有2路進氣,所以我們需要控制兩個氣泵,以及2路的PWM,每路可以單獨控制,在試驗時我們使用50%的占空比。
void PWM_Configuration(void) { //計算初始化的頻率和占空比 TimerPeriod = PWMTimePeriod;//計算用於設置ARR寄存器的值使產生信號的頻率為17.57 Khz PWM1Pulse = (uint16_t) (((uint32_t) 5 * (TimerPeriod - 1)) / 10);//計算CCR1寄存器的值在通道1和1N產生50%占空比,用於TIM1 PWM2Pulse = (uint16_t) (((uint32_t) 5 * (TimerPeriod - 1)) / 10);//計算CCR1寄存器的值在通道1和1N產生50%占空比,用於TIM8 PWM_InitProcess(TIM1,TimerPeriod,PWM1Pulse); }
其次我們說以說I2C控制,有好幾路傳感器都使用的是I2C數據通訊來實現,我們在這裏我們只說兩個基本的I2C操作函數,一個是下發命令,一個是讀取數據。所有的操作都刻以通過調用這兩個函數來實現。
/*向I2C從站下發指令,指令格式均為1個字節*/ void SendCommandToI2CSlave(I2C_TypeDef* I2Cx,uint8_t deviceAddress,uint8_t command) { uint16_t i2cTimeout=TimeoutPeriod; /*產生I2C起始信號*/ I2C_GenerateSTART(I2C2, ENABLE); /*檢測 EV5 事件並清除標誌*/ while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT)) { if ((i2cTimeout--) == 0) return ; } /*發送I2C從站的地址*/ I2C_Send7bitAddress(I2Cx,deviceAddress,I2C_Direction_Transmitter); i2cTimeout=TimeoutPeriod; /*檢測 EV6 事件並清除標誌*/ while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) { if ((i2cTimeout--) == 0) return ; } /*下發操作命令*/ I2C_SendData(I2Cx, command); i2cTimeout=TimeoutPeriod; /*檢測 EV8 事件並清除標誌*/ while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) { if ((i2cTimeout--) == 0) return ; } /* 產生I2C停止信號 */ I2C_GenerateSTOP(I2Cx, ENABLE); } /*從I2C從站讀取多個字節數據的值*/ void GetBytesFromI2CSlave(I2C_TypeDef* I2Cx,uint8_t deviceAddress,uint8_t *pData,uint16_t bytesNum) { uint16_t i2cTimeout=TimeoutPeriod; /*如果I2C總線忙,則等待一段時間*/ while (I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY)) { if ((i2cTimeout--) == 0) return ; } /* 產生 I2C 起始信號 */ I2C_GenerateSTART(I2Cx, ENABLE); /*檢測 EV5 事件並清除標誌*/ while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT)) { if ((i2cTimeout--) == 0) return ; } /*發送I2C從站的地址*/ I2C_Send7bitAddress(I2Cx,deviceAddress+1,I2C_Direction_Receiver); i2cTimeout=TimeoutPeriod; /*檢測 EV6 事件並清除標誌*/ while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) { if ((i2cTimeout--) == 0) return ; } while(bytesNum) { if(bytesNum==1) { I2C_AcknowledgeConfig(I2Cx, DISABLE);//關閉應答 I2C_GenerateSTOP(I2Cx, ENABLE);//停止信號 } i2cTimeout=TimeoutPeriod; /*檢測 EV7 事件並清除標誌*/ while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)) { if ((i2cTimeout--) == 0) return ; } /*通過 I2C,從設備中讀取一個字節的數據 */ *pData=I2C_ReceiveData(I2Cx); pData++; bytesNum--; } /*使能應答,方便下一次 I2C 傳輸*/ I2C_AcknowledgeConfig(I2Cx, ENABLE); }
接下來我們看看將數據存儲到本地SD卡的操作過程,數據保留2位小數,並且采用4舍5入處理。
//將數據寫入到SD卡 void WriteDataToSDCard(void) { //將數據寫入SD卡 saveData[0]=((int16_t)(tempProcessValue*100+0.5))/100.0;//溫度測量值 saveData[1]=((int16_t)(presProcessValue*100+0.5))/100.0;//壓力測量值 saveData[2]=((int16_t)(flowProcessValue1*100+0.5))/100.0;//流量計1的標況流量 saveData[3]=flowTatolVolume1;//流量計1的工況累計流量 saveData[4]=flowStdTatolVolume1;//流量計1的標況累計流量 saveData[5]=((int16_t)(flowProcessValue2*100+0.5))/100.0;//流量計2的標況流量 saveData[6]=flowTatolVolume2;//流量計2的工況累計流量 saveData[7]=flowStdTatolVolume2;//流量計2的標況累計流量 saveDate[0]=systemYear; saveDate[1]=systemMonth; saveDate[2]=systemDate; saveDate[3]=systemHour; saveDate[4]=systemMinute; saveDate[5]=systemSecond; SDCardFileOperation(); }
4、結果展示
我們在OneNET上創建了一個產品,6臺設備,以及4個應用,來驗證方案的效果,在測試過程中我們使用了Wifi方式來進行此次測試,因為這也是我們正是產品主要使用的連網方式。我們看一看數據上傳的趨勢圖:
接下來我們看看顯示位置及溫濕度的應用截圖:
我們再來看看顯示大氣壓、溫度和濕度的截圖:
我們再來看看氣體流量及柱狀圖顯示:
至此,我們的測試項目完成,再次感謝電子發燒友和中國移動OneNET給我們帶來的完美體驗。
OneNET麒麟座應用開發之十:空氣質量數據監測站項目總結