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);}

========================================================================

註:有關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的值,其他部分都可以刪除掉

=======================================================

註:有關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);

}