實際運作的影片
*後來把顯示的方式做了修改。把PM1和10拿掉,只留下PM2.5和溫濕度
PMS3003長這樣,上面就是風扇,然後接頭有八個pin,附的接線就是八條線。但實際上接在arduino上,如果只要讀數值的話,只要三條就夠了。從最右邊的藍色開始算第一條的話,就是1, 2, 5,三條線。
1是VCC, 2是GND, 5就是訊號了。我原本以為要四條,因為查到的資料都是1, 2, 4, 5分別要接VCC, GND, RX->TX和TX->RX,這可能有別的特殊功能吧,後來發現用不到(我還沒弄懂),最後其實只有用到三條接線。
本來要接到arduino的RX上的線,我最後決定接到D7上,不然每次上傳都要拔線,很麻煩。既然不需要特別用到arduino上的RX, TX,我就改接點了比較方便。最後就是把三個接點接到D7的VCC, GND和Signal。
程式碼如下:
#include <LiquidCrystal_I2C.h>
// Set the pins on the I2C chip used for LCD connections:
// addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // 設定 LCD I2C 位址
//以上是驅動LCD的部分
#include <Wire.h>
#include <dht.h> //使用DHT11 LibraryLiquidCrystal_I2C lcd(0x27,16,2);
dht DHT; //定義DHT11 物件
#define dht_dpin 4 //定義讀取資料的 Pin腳
#include <SoftwareSerial.h>
#define pinR 9
#define pinG 10
#define pinB 11
SoftwareSerial mySerial(7, 1); // RX, TX
long pmcf10=0;
long pmcf25=0;
long pmcf100=0;
long pmat10=0;
long pmat25=0;
long pmat100=0;
char buf[50];
int r = 0;
int g = 0;
int b = 0;
void setup() {
lcd.begin(16,2);
pinMode(pinR, OUTPUT);
pinMode(pinG, OUTPUT);
pinMode(pinB, OUTPUT);
pinMode(Buzzer, OUTPUT);
Serial.begin(9600);
mySerial.begin(9600);
delay(300); //Let system settle
}
void loop() {
retrievepm25();
}
void retrievepm25(){
DHT.read11(dht_dpin); //去library裡面找DHT.read11
Serial.print("Humidity = ");
Serial.print(DHT.humidity);
Serial.print("% ");
Serial.print("temperature = ");
Serial.print(DHT.temperature);
Serial.println("C ");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("H=");
lcd.print(DHT.humidity);
lcd.print("%");
lcd.print("T=");
lcd.print(DHT.temperature);
lcd.println("C");
int count = 0;
unsigned char c;
unsigned char high;
while (mySerial.available()) {
c = mySerial.read();
if((count==0 && c!=0x42) || (count==1 && c!=0x4d)){
Serial.println("check failed");
break;
}
if(count > 15){
Serial.println("complete");
break;
}
else if(count == 4 || count == 6 || count == 8 || count == 10 || count == 12 || count == 14) {
high = c;
}
else if(count == 5){
pmcf10 = 256*high + c;
Serial.print("PM1.0=");
Serial.print(pmcf10);
Serial.println(" ug/m3");
}
else if(count == 7){
pmcf25
= 256*high + c;
Serial.print("PM2.5=");
Serial.print(pmcf25);
Serial.println(" ug/m3");
lcd.setCursor(0,1);
lcd.print ("PM2.5=");
lcd.print (pmcf25);
lcd.print (" ug/m3");
if (pmcf25 < 15.4) {
r=0;
g=40;
b=0;
noTone(5);
}
else if (pmcf25 < 35.4){
r=40;
g=40;
b=0;
noTone(5);
}
else if(pmcf25<55.4){
r=50;
g=30;
b=0;
noTone(5);
}
else if(pmcf25 <150.4){
r=80;
g=0;
b=0;
noTone(5);
}
else if(pmcf25 <251.4){
r=40;
g=0;
b=40;
noTone(5);
}
else if (pmcf25 >251.4){
tone (5, 500, 1000);
r=162;
g=42;
b=42;
}
analogWrite (9 ,r);
analogWrite (10 ,g);
analogWrite (11 ,b);
}
else if(count == 9){
pmcf100 = 256*high + c;
Serial.print("PM10 =");
Serial.print(pmcf100);
Serial.println(" ug/m3");
}
count++;
}
while(mySerial.available()) mySerial.read();// 將多餘的資料掠過
Serial.println();
delay(1000);
}
光是這樣就可以從serial print上讀到數值囉。然後我想既然用了EMS, 不如就利用上面的DHT11溫濕度計,加上三色LED燈和蜂鳴器來做一些事情。
首先就是加上LCD, 把訊息顯示在LCD上。然後顯示溫濕度。這樣幾個重要的環境偵測數值就都有了(改天再把大氣壓力加上去好了)然後發現LCD太小,所以訊息得要交替出現。
接下來依據最新的空氣污染指標AQI,將PM2.5的數值轉成AQI對應的顏色,顯示在三色LED燈上面。定義在這邊
所以pm2.5在 15.4 ug/m3以下,是綠色的; 15.4~35.4是黃色的這樣以此類推...,接下來只要抓取pm2.5的數值來設定條件對應輸出的顏色就行。最後再加上蜂鳴器,讓污染值太高的時候,會發生一些警告聲音,就完成了。
一開始是綠色的
點上蠟燭,還是綠的
吹熄之後,冒一些煙出來,pm2.5瞬間破表,飆到2906 ug/m3,顯示亮橘色(原本的深褐色在LED上不太好表達,我就把亮度調高變成亮橘色)
幾秒之後,降到228 ug/m3,但是超級怪異的是,紫色一直出不來,完全無法理解(結果只要在那個條件加上buzzer要發出聲音,LED的藍色就會消失,完全無法理解問題!後來只好把紫色的聲音警告關掉)
幾秒鐘之後,下降到33ug/m3, 變成黃色
code等我抓到bug再放上來囉
沒有留言:
張貼留言