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

晒寶貝喔!分享一下您精心製作的pm2.5感測器~~

discuss pic 2016-07-25 20:41:07
大家架設好後,不仿拍個照,甚至架設中的英姿~~好讓其他老師參考,大家分享一下喔~~
discuss pic 2016-07-26 22:34:05
discuss pic 2016-07-30 15:47:10
水喔!水喔!擺著當展示,MAKER環境教育喔~
discuss pic 2016-08-04 21:27:06
我把感測器裝到盒子上方,方便跟學生說明。


盒子側面只挖電源孔。


未來打算把4個LED燈移到盒子外面方便觀察,順便貼上監測網站的 QR code。

感謝鄭老師,自己動手做很好玩^^
discuss pic 2016-08-04 22:32:38
太讚了~~~~~~,還想到把LED燈外移,這是個好構想!感謝嘉龍老師分享
discuss pic 2016-08-04 23:35:01

一代目偵測器(第一梯研習,只有sharp傳感器+無線模組)



二代目偵測器(第二梯研習,加裝溫濕度感測+LED指示)
綠光LED顏色容易搞混,所以換成白光LED!


以第二梯研習送的塑膠盒當比例尺!(粉紅色盒子是閩南語認證的小禮物外盒


 實際上線工作情況影片



話說第一梯研習給的sharp GY1010傳感器會有偵測數值偏高的情形,上線後常常看到網頁顯示一片紫!

小弟當時的作法:





後來上網google,找到幾個不同寫法的偵測判斷程式,有興趣的參考囉!


discuss pic 2016-08-05 00:52:55
哈哈,真是有趣~~

不過,樂文老師,提供的兩個網址參數的換算公式應該都差不多,我也有參考到這兩篇,後來改成國外數據曲線的原始計算方式,不知道是不是真的有些感測器有問題,還是線路接觸不良的問題?需要大家一起來找看看解法....
discuss pic 2016-08-05 16:57:57
PM2.5精簡版~~~

ESP8266其實可以像UNO板一樣當作主控版,
這次研習配發的是ESP-01,只有兩個GPIO,一個給DHT22用,一個給SHARP(二代)用,
就沒法再接LED.蜂鳴器.繼電器,較不適合教學展示(全接的話可用ESP-12),
不過若是純粹記錄資料用,倒是可以省下UNO板跟很多小零件
-------
更正一下:
DHT22佔用一個GPIO,而SHARP則是接到RX,
所以還空出一個GPIO可以利用,如接蜂鳴器嗶嗶叫,
或是接顆IR LED更讚,整組放在冷氣機附近,就可以紅外線搖控冷氣機了~~~
discuss pic 2016-08-07 08:32:30
天哪!宇男老師實在是太強了!這本來是未來的進階課程,沒想到你自行完成!!實在太了不起了,我畫了電路圖,麻煩老師可否提供一下程式,大家有福了~~

discuss pic 2016-08-07 21:19:06
感謝盛南老師的電路圖,清楚明瞭~~
小弟的程式碼,供大家參考,內容是拜請孤狗大神拼湊而來的,為了方便閱讀有些原作的註解已刪減了(不良示範)
本例中並沒有使用蜂鳴器,這部份就麻煩盛南老師看要讓它怎麼叫了...

#include <DHT.h> #include <ESP8266WiFi.h> #define DHTPIN 0 //#define BUZZPIN 2 #define DHTTYPE DHT22 DHT dht(DHTPIN, DHTTYPE,11); //*-- IoT Information #define SSID "修改無線網路名稱" //無線網路名稱 #define PASS "修改無線網路密碼" //無線網路密碼 #define HOST "pm25.tn.edu.tw" //PM2.5網站網址 #define PORT 80 String PMgps = "修改學校經緯度座標"; //學校經緯度座標 String schoolcode = "修改學校代碼"; //學校代碼 int no = 0; //設備編號,可設定0~255,在監測網上可區別一校多個設備 long updateInterval = 1200000; //傳送資料時間間隔,測試完請設定1800000(30分鐘) long resettime =86400000; //每24小時自動重開機 //sharp GP2Y1051 二代 start int incomeByte[7]; int data; int z=0; float T; int sum, sount; unsigned long error, starttime; void setup() { Serial.begin( 2400 ); Serial.println( SSID ); WiFi.begin( SSID, PASS ); dht.begin(); starttime=millis(); //設定Sharp感測器開始的擷取時間 delay(2000); } void loop() { if(starttime >= resettime) { ESP.restart(); } 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; } else{ z=0; Serial.flush(); data='/0'; for(int m=0;m<7;m++){ incomeByte[m]=0; } } z=0; } } updateSensor(T); delay(updateInterval); // 設定傳送時間間隔 } void updateSensor( float T) { float h = dht.readHumidity(); float t = dht.readTemperature(); WiFiClient client; if( !client.connect( HOST, PORT ) ) { return; } else { String getStr = "GET /xoops/api.php?schoolcode=" + schoolcode + "&no=" + no + "&pm25=" + T + "&t=" + t + "&h=" + h +"&gps=" + PMgps + " HTTP/1.1\r\n"; client.print( getStr ); client.print( "Host: pm25.tn.edu.tw\n" ); client.print( "Connection: close\r\n\r\n" ); delay(5000); client.stop(); } }

discuss pic 2016-08-07 22:47:58
    真是太棒了!原來高手就在身邊,放上buzzer的部分,請多指教一下,也可以從雲端下載
雲端→Arduino程式→1050722→ESP8266_Buzzer_DHT22_air2_sample
    大家也可以玩玩看,不過,燒錄方式需要用到esp8266 to usb轉接器,並且參考 http://ruten-proteus.blogspot.tw/2015 ... -support-arduino-ide.html 中,用Arduino IDE程式匯入ESP8266的程式庫,設定相關參數,如1MB 512+512,若覺得太複雜,就請等我將ESP8266講義完成,或者是.....宇男兄可以讓你嶄露身手一下.....^^

#include <DHT.h>
#include <ESP8266WiFi.h>
#define  DHTPIN     0
#define  BUZZPIN    2    
#define  DHTTYPE    DHT22 
DHT dht(DHTPIN, DHTTYPE);

//*-- IoT Information
#define SSID    "修改無線網路名稱"      //無線網路名稱
#define PASS    "修改無線網路密碼"      //無線網路密碼
#define HOST    "pm25.tn.edu.tw"        //PM2.5網站網址
#define PORT    80
String PMgps = "修改學校經緯度座標";   //學校經緯度座標
String schoolcode = "修改學校代碼";    //學校代碼
int no = 0;                            //設備編號,可設定0~255,在監測網上可區別一校多個設備
long updateInterval = 1200000;    //傳送資料時間間隔,測試完請設定1800000(30分鐘)
long resettime =86400000;       //每24小時自動重開機

//sharp GP2Y1051 二代 start
int incomeByte[7];
int data;
int z=0;
float T;
int sum, sount;
unsigned long error, starttime;

void setup() {
    Serial.begin( 2400 );
    Serial.println( SSID );
    WiFi.begin( SSID, PASS );
    dht.begin();
    pinMode( DHTPIN, INPUT );
    pinMode( BUZZPIN, OUTPUT );
    digitalWrite( BUZZPIN, OFF );    
    starttime=millis();      //設定Sharp感測器開始的擷取時間
    delay(2000);
}

void loop() {
   if(starttime >= resettime) {
    ESP.restart();  
    }
 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;
   
      }
      else{
        z=0;
        Serial.flush();
        data='/0';
        for(int m=0;m<7;m++){
          incomeByte[m]=0;
          }
      }
      z=0;
    }
  }
          updateSensor(T);
          delay(updateInterval);   // 設定傳送時間間隔  
}

void updateSensor( float T)
{
   if(T>200) {
      digitalWrite( BUZZPIN, ON );
               delay(1000);
      digitalWrite( BUZZPIN, OFF );
               delay(1000);
      digitalWrite( BUZZPIN, ON );
               delay(1000);
      digitalWrite( BUZZPIN, OFF );
               delay(1000);
      digitalWrite( BUZZPIN, ON );
               delay(1000);
      digitalWrite( BUZZPIN, OFF );
      }

    float h = dht.readHumidity();
    float t  = dht.readTemperature();
 
    WiFiClient client;
    if( !client.connect( HOST, PORT ) )
    {
       return;
    }
    else
    {
        String getStr = "GET /xoops/api.php?schoolcode=" + schoolcode + "&no=" + no + "&pm25=" + T + "&t=" + t + "&h=" + h +"&gps=" + PMgps + " HTTP/1.1\r\n";
        client.print( getStr );
        client.print( "Host: pm25.tn.edu.tw\n" );
        client.print( "Connection: close\r\n\r\n" );
        
        delay(5000);
        client.stop();
      }
}


discuss pic 2016-08-08 07:48:43
盛南老師,小小問題請教一下:
為了節省資料庫資源所以設定每30分鐘才上傳資料一次,
不過LED與蜂鳴器的反應與資料庫無關,
是不是可以從UpdateSensor()裡面獨立出來,
讓它可以即時改變LED燈號或是鳴叫聲,
不用等30分後要寫入資料庫時才變更,
這樣在教學展示時較能看到它的變化
以上一點小建議
discuss pic 2016-08-08 16:44:04
是的,這也是有想到的,只是比較沒時間修改及測試程式sorry,還可以考慮收個幾次資料再上傳平均值等,這都是可以思考的部分

其實我自己還有測試在Arduino內做一個小網站,可以直接連上去察看即時的數據,有時間會再分享出來....

宇男老師,可以的話幫忙修改測試一下,^^
discuss pic 2016-08-22 09:01:02
經過不到一個月,有兩個燈似乎壞了,另一個亮度已經漸暗了,但是資料還是會上傳,請問是LED燈的品質問題?還是應該再加上電阻來避免LED燈燒毀?
  •  
    1) image.jpeg
  •  
    2) image.jpeg
discuss pic 2016-08-24 13:01:18
老師,請參考此討論串最後的內容,感謝。
http://pm25.tn.edu.tw/xoops/modules/t ... DiscussID=6&BoardID=1
discuss pic 2016-08-25 08:21:42
LED不加電阻的話可以改用PWN輸出減少出力,
支援PWM的腳位是3.5.6.9.10.11,
藍紅黃燈已接到11.10.9了,只需把綠燈改接到3
再把原本控制LED開關的語法digitalWrite(腳位,開/關), 開關HIGH/LOW,ON/OFF,1/0都通用
改成analogWrite(腳位,0~255) ,0關閉,255最亮,
找一個LED可以看得清楚不會太暗的數值,
延長LED的壽命,
以上供各位參考