02-G3+MH-Z19+DHT11+LCD+arduino
(2017/03/27)
這次將G3(測PM2.5)、MH-Z19(測CO2)、DHT11(測溫濕度)、LCD(顯示用) 與 arduino Uno控制板做一個結合,完成一個可測PM2.5、CO2濃度、溫濕度的一個設備!
所需設備:
Arduino Uno控制板
PMS3003 G3(測PM2.5)
MH-Z19 (測CO2)
DHT11 (測溫濕度)
LCD (顯示用)
LED燈 (綠色、黃色、紅色)
接線說明:
PMS3003 G3 (測PM2.5):參考先前的文章,將G3的第五條線(綠色)接Arduino的D2(可自選),另外第一條線(紫色)接VCC、第二條線(橘色)接GND
MH-Z19 (測CO2):參考先前的文章,採用PWM的方式(ppm3)來讀取資料,因為pwm3的值與UART的值相近,將MH-Z19的PWM接Arduino的D6(可自選),另外Vin接VCC、GND接GND
DHT11 (測溫濕度):將DHT11的S接Arduino的D4(可自選),另外 + 接VCC、- 接GND
LCD (顯示用) :將LCD的SDA接Arduino的A4、SCL接Arduino的A5,另外VCC接VCC、GND接GND
LED燈 (綠色、黃色、紅色):綠色LED燈接D8、黃色LED燈接D9、紅色LED燈接D9
作品外觀:
程式說明,先各設備各別說明
DHT11:利用Motoblockly來寫程式,再轉為Arduino語言,程式如下
#include <Wire.h>#include <motoLiquidCrystal_I2C.h>#include <motoDHT.h>LiquidCrystal_I2C mylcd(0x3F,16,2); DHT motoDHT(4, DHT11);void setup(){ mylcd.init(); mylcd.backlight(); pinMode(4, INPUT); motoDHT.begin();}void loop(){ mylcd.clear(); mylcd.setCursor(0,0); mylcd.print(String("T : ") + String(motoDHT.readTemperature()) + String("(C) ")); mylcd.setCursor(0,1); mylcd.print(String("H : ") + String(motoDHT.readHumidity()) + String("(%)")); delay(1000);}
========================================================================
PMS3003 G3:參考先前的文章
註:有關LCD顯示器的程式,採用Motoblockly的積木來產生(紅色字為增加的地方)
#include <SoftwareSerial.h>
#include <Wire.h>
#include <motoLiquidCrystal_I2C.h>
LiquidCrystal_I2C mylcd(0x3F,16,2);
SoftwareSerial Serial1(2, 3); // RX, TX
long pmcf10=0;
long pmcf25=0;
long pmcf100=0;
long pmat10=0;
long pmat25=0;
long pmat100=0;
char buf[50];
void setup() {
// put your setup code here, to run once:
mylcd.init();
mylcd.backlight();
Serial.begin(9600);
Serial1.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
int count = 0;
unsigned char c;
unsigned char high;
while (Serial1.available()) {
c = Serial1.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("CF=1, PM1.0=");
Serial.print(pmcf10);
Serial.println(" ug/m3");
mylcd.setCursor(0,0);
mylcd.print(String("CF ")+pmcf10 + String(","));
}
else if(count == 7){
pmcf25 = 256*high + c;
Serial.print("CF=1, PM2.5=");
Serial.print(pmcf25);
Serial.println(" ug/m3");
mylcd.setCursor(8,0);
mylcd.print(pmcf25 + String(","));
}
else if(count == 9){
pmcf100 = 256*high + c;
Serial.print("CF=1, PM10=");
Serial.print(pmcf100);
Serial.println(" ug/m3");
mylcd.setCursor(12,0);
mylcd.print(pmcf100);
}
else if(count == 11){
pmat10 = 256*high + c;
Serial.print("atmosphere, PM1.0=");
Serial.print(pmat10);
Serial.println(" ug/m3");
mylcd.setCursor(0,1);
mylcd.print(String("At ")+pmat10 + String(","));
}
else if(count == 13){
pmat25 = 256*high + c;
Serial.print("atmosphere, PM2.5=");
Serial.print(pmat25);
Serial.println(" ug/m3");
mylcd.setCursor(8,1);
mylcd.print(pmat25 + String(","));
}
else if(count == 15){
pmat100 = 256*high + c;
Serial.print("atmosphere, PM10=");
Serial.print(pmat100);
Serial.println(" ug/m3");
mylcd.setCursor(12,1);
mylcd.print(pmat100);
}
count++;
}
while(Serial1.available()) Serial1.read();
Serial.println();
delay(5000);
}
那六組資料會顯示在序列埠及LCD顯示器上,但在這只顯示pmat25的值,其他部分都可以刪除掉
=======================================================
MH-Z19 (測CO2):參考先前的文章
註:有關LCD顯示器的程式,採用Motoblockly的積木來產生(紅色字)
#include <SPI.h>
#include <Wire.h>
#include <motoLiquidCrystal_I2C.h>
LiquidCrystal_I2C mylcd(0x3F,16,2);
#include <SoftwareSerial.h>
#define pwmPin 10 //接D10
int preheatSec = 30; //預熱時間
unsigned long th, tl, ppm3 = 0;
void setup() {
mylcd.init();
mylcd.backlight();
Serial.begin(9600);
pinMode(pwmPin, INPUT);
}
void loop() {
//CO2 via pwm
do {
th = pulseIn(pwmPin, HIGH, 1004000) / 1000;
tl = 1004 - th;
// ppm2 = 2000 * (th-2)/(th+tl-4);
ppm3 = 5000 * (th-2)/(th+tl-4);
} while (th == 0);
// Serial.println(ppm2); //PWM (0-2000PPM)
// Serial.println(ppm3); //PWM (0-5000PPM)
// Serial.println("-----------");
mylcd.clear();
mylcd.setCursor(0,0);
mylcd.print(String("CO2 PPM"));
mylcd.setCursor(0,1);
mylcd.print(ppm3);
delay(1000);
}
原本程式會顯示UART、PWM二組的資料,但在這只顯示PWM的ppm3的值,其他部分都可以刪除掉
=================================================================
程式說明,將所有設備整合在一起,成一支程式(沒有加入LED燈,檔案於附件)
紅色:G3(測PM2.5)、藍色:MH-Z19 (測CO2)
粉紅色:DHT11(測溫濕度)、紫色:LCD顯示器
#include <SoftwareSerial.h>
#include <Wire.h>
#include <motoDHT.h>
#include <motoLiquidCrystal_I2C.h>
LiquidCrystal_I2C mylcd(0x3F,16,2);
SoftwareSerial Serial1(2, 3); // RX, TX //接D2
long pmat25=0;
char buf[50];
#define pwmPin 6 //接D6
unsigned long th, tl, ppm3 = 0;
DHT motoDHT(4, DHT11); //接D4
void setup()
{
mylcd.init();
mylcd.backlight();
Serial.begin(9600);
Serial1.begin(9600);
pinMode(pwmPin, INPUT);
pinMode(4, INPUT);
motoDHT.begin();
}
void loop()
{
mylcd.clear();
mylcd.setCursor(0,0);
mylcd.print(String("T : ") + String(motoDHT.readTemperature()) + String("(C) "));
mylcd.setCursor(0,1);
mylcd.print(String("H : ") + String(motoDHT.readHumidity()) + String("(%)"));
delay(1000);
//CO2 via pwm
do {
th = pulseIn(pwmPin, HIGH, 1004000) / 1000;
tl = 1004 - th;
ppm3 = 5000 * (th-2)/(th+tl-4);
} while (th == 0);
mylcd.clear();
mylcd.setCursor(0,0);
mylcd.print(String("CO2 : ")+ppm3);
int count = 0;
unsigned char c;
unsigned char high;
while (Serial1.available()) {
c = Serial1.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 == 13){
pmat25 = 256*high + c;
mylcd.setCursor(0,1);
mylcd.print( String("PM2.5: ")+pmat25 );
}
count++;
}
while(Serial1.available()) Serial1.read();
Serial.println();
delay(3000);
}
=================================================================
程式說明,再加上LED燈顯示PM2.5值(檔案於附件)
PM2.5<=35,顯示綠燈
35<PM2.5<=53,顯示黃燈
53<PM2.5<=70,顯示紅燈
70<PM2.5 ,三燈都亮
long pm25;void setup(){ pinMode(8, OUTPUT); pinMode(9, OUTPUT); pinMode(10, OUTPUT); pm25 = 0;}void loop(){ if (pm25 <= 35 || pm25 > 70) { digitalWrite(8,HIGH); } else { digitalWrite(8,LOW); } if (pm25 > 35 && pm25 <= 53 || pm25 > 70) { digitalWrite(9,HIGH); } else { digitalWrite(9,LOW); } if (pm25 > 53) { digitalWrite(10,HIGH); } else { digitalWrite(10,LOW); }}
#include <SoftwareSerial.h>
#include <Wire.h>
#include <motoDHT.h>
#include <motoLiquidCrystal_I2C.h>
LiquidCrystal_I2C mylcd(0x3F,16,2);
SoftwareSerial Serial1(2, 3); // RX, TX //接D2
long pmat25=0;
char buf[50];
#define pwmPin 6 //接D6
unsigned long th, tl, ppm3 = 0;
DHT motoDHT(4, DHT11); //接D4
void setup()
{
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
mylcd.init();
mylcd.backlight();
Serial.begin(9600);
Serial1.begin(9600);
pinMode(pwmPin, INPUT);
pinMode(4, INPUT);
motoDHT.begin();
}
void loop()
{
mylcd.clear();
mylcd.setCursor(0,0);
mylcd.print(String("T : ") + String(motoDHT.readTemperature()) + String("(C) "));
mylcd.setCursor(0,1);
mylcd.print(String("H : ") + String(motoDHT.readHumidity()) + String("(%)"));
delay(1000);
//CO2 via pwm
do {
th = pulseIn(pwmPin, HIGH, 1004000) / 1000;
tl = 1004 - th;
ppm3 = 5000 * (th-2)/(th+tl-4);
} while (th == 0);
mylcd.clear();
mylcd.setCursor(0,0);
mylcd.print(String("CO2 : ")+ppm3);
int count = 0;
unsigned char c;
unsigned char high;
while (Serial1.available()) {
c = Serial1.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 == 13){
pmat25 = 256*high + c;
mylcd.setCursor(0,1);
mylcd.print( String("PM2.5: ")+pmat25 );
if (pmat25 <= 35 || pmat25 > 70) {
digitalWrite(8,HIGH);
} else {
digitalWrite(8,LOW);
}
if (pmat25 > 35 && pmat25 <= 53 || pmat25 > 70) {
digitalWrite(9,HIGH);
} else {
digitalWrite(9,LOW);
}
if (pmat25 > 53) {
digitalWrite(10,HIGH);
} else {
digitalWrite(10,LOW);
}
}
count++;
}
while(Serial1.available()) Serial1.read();
Serial.println();
delay(3000);
}