:::
PM2.5空污監測器實作

關於PM2.5二代目傳感器的語法

discuss pic 2016-08-06 20:08:01
上傳資料時好像前幾筆資料,T的值都是空氣良好(0.00),而溫溼度的值則是正常,
傳感器的孔塞入異物,監測網頁也是要等更新幾輪後才會出現紫色,
不知各位使用二代目的先進是否也有此"累格"現象?

研習時測試10秒上傳一次,開機後差不多一分鐘後才有正常數值,
回來改成30分鐘上傳一次,則是3~4個小時後才有正常數值,
若是常常自動RESET(聽到繼電器搭搭塔的聲音就是了),一天下來報表裡就會一堆0.00

研究鄭老師的程式碼時,看到傳感器在取值時Z是從0~6,跑7個循環
感覺跟上面的"累格"似乎有點關聯,
亂改測試一下好像正常了,修改如下:
updateSensor(T);
delay(updateInterval);   
這兩行搬到while迴圈外,loop()之內,另外T變數改放到前幾行宣告,不然編譯時會出現錯誤訊息

修改後的程式碼供各位先進參考:
void loop() {
  
 while (Serial.available()>0){
    data=Serial.read();
    if(data == 170){
      z=0;
      incomeByte[z]=data;
    }
    else{
      z++;
      incomeByte[z]=data;
    } 
    if(z==6)
    {
      sum=incomeByte[1]+ incomeByte[2]+ incomeByte[3] + incomeByte[4];
 
      if(incomeByte[5]==sum && incomeByte[6]==255 )
      {
 
        float vo=(incomeByte[1]*256.0+incomeByte[2])/1024.0*5.00;
   
       T = vo*700;
   
   //     updateSensor(T);
   //     delay(updateInterval);   // 設定傳送時間間隔  
      }
      else{
        z=0;
        Serial.flush();
        data='/0';
        for(int m=0;m<7;m++){
          incomeByte[m]=0;
          }
      }
      z=0;
    }
  }
          updateSensor(T);
          delay(updateInterval);   // 設定傳送時間間隔  
}
discuss pic 2016-08-07 00:35:54
太棒了!感謝宇男老師的分享,大家測試看看,我星期一測試完後,再跟大家報告
discuss pic 2016-08-09 01:28:27
改完了,幫忙測試看看
雲端→Arduino程式→1050722→LED4_Buzzer_DHT22_ESP8266_Relay_air2_sample_0809

修改或新增的功能有:
1. 每兩秒鐘加總平均一次感測值,並顯示在LED上。
2. 感測反應正常,不遲鈍:放異物進入感測孔,會隨即出現藍燈並蜂鳴器告警,移開後兩到三秒即解除告警,回復正常燈號。
3. Relay2驅動的設備運作時間,可由設定 Relay2Interval 變數來控制,預設20分鐘。

再次感謝宇男老師的協助~~

#include <SoftwareSerial.h> #include <DHT.h> #define _rxpin 4 //接ESP8266 TX #define _txpin 5 //接ESP8266 RX #define RST 6 //接ESP8266 RST #define DHTPIN 7 //接DHT22資料傳輸 #define LED_G 8 //接綠燈 #define LED_Y 9 //接黃燈 #define LED_R 10 //接紅燈 #define LED_B 11 //接藍(紫)燈 #define Relay2 12 //Control Fan or Light #define Buzzer 13 //接蜂鳴器 #define DHTTYPE DHT22 // SENSOR TYPE - THE ADAFRUIT LIBRARY OFFERS SUPPORT FOR MORE MODELS DHT dht(DHTPIN, DHTTYPE); SoftwareSerial WiFiSerial( _rxpin, _txpin ); // ESP8266 RX, TX //*-- IoT Information String SSID = "TN-Computer-bridge"; //無線網路名稱 String PASS = "computer123"; //無線網路密碼 //String SSID = "修改自己的無線網路名稱"; //無線網路名稱 //String PASS = "修改自己的無線網路密碼"; //無線網路密碼 String schoolcode = "修改自己的學校代碼"; //學校代碼 int no = 0; //設備編號,可設定0~255,在監測網上可區別一校多個設備 String PMgps = "修改自己的學校經緯度"; //學校經緯度座標 //long updateInterval = 1800000; //傳送資料時間間隔,測試完請設定1800000(30分鐘) long updateInterval = 10000; //傳送資料時間間隔,測試用10000(10秒鐘) 時間太短亦會發生錯誤 long Relay2Interval = 1200000; //設定Relay2控制的設備運作時間長短,1200000(20分鐘) String IP = "pm25.tn.edu.tw"; //PM2.5網站網址 //sharp GP2Y1051 二代 start int incomeByte[7]; int data; int z=0; int sum, count; float average_pm2d5,sum_2s; unsigned long error, starttime, buzzerStart, updateStart, Relay2Start; void sendtoWiFi(String cmd) { Serial.print("SEND: "); Serial.println(cmd); WiFiSerial.println(cmd); } boolean connectWiFi() { WiFiSerial.println("AT+CWMODE=1"); Serial.println("Send AT+CWMODE=1"); delay(3000); String cmd="AT+CWJAP=\"" + SSID + "\",\"" + PASS + "\""; sendtoWiFi(cmd); Serial.println("Waiting for 15 second to connect network ....."); delay(15000); cmd = "AT+ CIPMUX=0"; sendtoWiFi( cmd ); if( WiFiSerial.find( "Error") ) { Serial.print( "RECEIVED: Error" ); return false; } } void updateSensor( float T) { digitalWrite(LED_G,LOW); digitalWrite(LED_Y,LOW); digitalWrite(LED_R,LOW); digitalWrite(LED_B,LOW); if(T>=0 && T<36) { digitalWrite(LED_G,HIGH); } else if(T>=36 && T<54) { digitalWrite(LED_Y,HIGH); } else if(T>=54 && T<71) { digitalWrite(LED_R,HIGH); } else if(T>=71 && T<200) { digitalWrite(LED_B,HIGH); } else { //T>=200 digitalWrite(LED_B,HIGH); digitalWrite(Relay2,LOW); digitalWrite(Buzzer,HIGH); Relay2Start=millis(); //設定Relay2運作開始時間 buzzerStart=millis(); //設定Buzzer告警開始時間 } if(abs(millis()-buzzerStart)>2000){ digitalWrite(Buzzer,LOW); } if(abs(millis()-Relay2Start)>Relay2Interval){ digitalWrite(Relay2,HIGH); } if(abs( millis() - updateStart) > updateInterval | updateStart == 0 ){ // 設定 ESP8266 作為 Client 端 String cmd = "AT+CIPSTART=\"TCP\",\"" + IP + "\",80"; sendtoWiFi(cmd); delay(500); if( WiFiSerial.find("Error") ) { Serial.print( "RECEIVED: Error\nExit1" ); return; } float h = dht.readHumidity(); float t = dht.readTemperature(); boolean sendOK = false; cmd = "GET /xoops/api.php?schoolcode=" + schoolcode + "&no=" + no + "&pm25=" + T + "&t=" + t + "&h=" + h + "&gps=" + PMgps + "\r\n"; sendtoWiFi("AT+CIPSEND=" + (String)cmd.length()); delay(500); if(WiFiSerial.find( ">" ) ) { Serial.print(">"); WiFiSerial.print(cmd); //送出pm2.5資料 if( WiFiSerial.find("OK") ){ //檢查WiFi模組是否正確傳出資料 sendOK = true; } Serial.print(cmd); updateStart = millis(); //重設上傳時間 } else { sendtoWiFi( "AT+CIPCLOSE" ); } if(sendOK) { Serial.println( "RECEIVED: OK" ); } else { Serial.println( "RECEIVED: Error\nExit2" ); // reset ESP8266 digitalWrite(RST,LOW); //need chang to HIGH if Relay use HIGH active delay(500); digitalWrite(RST,HIGH); //need chang to LOW if Relay use HIGH active } } } void setup() { Serial.begin(2400); dht.begin(); WiFiSerial.begin(9600); starttime = millis(); //設定Sharp感測器開始的擷取時間 updateStart = millis(); //設定第一次即上傳 sendtoWiFi("AT"); delay(1000); if(WiFiSerial.find("OK")) { Serial.println("RECEIVED: OK after AT Command\nData ready to sent!"); connectWiFi(); } else{ Serial.println("fale"); } pinMode(LED_G,OUTPUT); pinMode(LED_Y,OUTPUT); pinMode(LED_R,OUTPUT); pinMode(LED_B,OUTPUT); pinMode(RST,OUTPUT); pinMode(Relay2,OUTPUT); pinMode(Buzzer,OUTPUT); digitalWrite(LED_G,LOW); digitalWrite(LED_Y,LOW); digitalWrite(LED_R,LOW); digitalWrite(LED_B,LOW); digitalWrite(RST,HIGH); digitalWrite(Relay2,HIGH); } void loop(){ while (Serial.available()>0){ data=Serial.read(); if(data == 170){ z=0; incomeByte[z]=data; } else{ z++; incomeByte[z]=data; } if(z==6) { sum=incomeByte[1]+ incomeByte[2]+ incomeByte[3] + incomeByte[4]; if(incomeByte[5]==sum && incomeByte[6]==255 ) { float vo=(incomeByte[1]*256.0+incomeByte[2])/1024.0*5.00; float pm = vo*700; sum_2s=sum_2s + pm; count++; if(abs(millis()-starttime)>2000){ average_pm2d5=(sum_2s/count)*1.00; updateSensor(average_pm2d5); Serial.print("PM2.5_Average = "); Serial.println(average_pm2d5,2); starttime=millis(); sum_2s=0; count=0; } } else{ z=0; Serial.flush(); data='/0'; for(int m=0;m<7;m++){ incomeByte[m]=0; } } z=0; } } }
discuss pic 2016-08-10 17:57:10
盛南老師三更半夜還在改程式,辛苦了

今天收到淘寶寄來的NODEMCU(ESP-12),就順便來測試一下老師的程式
很讚,PM2.5的偵測孔一塞入東西,馬上亮藍燈+鳴叫
搭配行動電源,戶外趴趴造也沒問題

原本想再加顆IR LED透過紅外線遙控冷氣,讓它自動開冷氣,不過代誌不是憨郎所想的架尼簡單,冷氣的紅外線遠比電視音響的紅外線複雜許多,殘念了

discuss pic 2016-08-11 10:41:23
請問宇男老師,為什麼你的dht 1,2腳為什麼不像南老師串上一個電阻?
是否有教學文,感覺你的元件又更少了,小弟也想自己組一個試試看,謝謝。

discuss pic 2016-08-11 16:35:04
李老師好,電阻是有加的,怕發熱影響溫度偵測值所以擺在DHT22後面
上圖所用的NODEMCU,它的功能就等於[USB to 8266轉接板]+[UNO板]+[ESP8266]
所以減少了很多的接線,而且成本也便宜,淘寶一塊人民幣20元不到,CP值爆高
只是接腳數沒有像UNO那麼多,不過也夠用了

我買過2種不同版本的NODEMCU,差別只在於USB驅動不同(大片的是用CH340,小片的是用CP2012)
大片的會塞滿麵包板,不好再插杜邦線,不建議使用

ESP8266有十幾種型號,
NODEMCU上面內嵌的是ESP-12,有8個可用接腳
這次研習使用的ESP-01,有兩個可用接腳,
大家手邊能玩的只有ESP-01,使用教學晚點再補上