2.與NodeMCU連接(下圖接在RX、TX),藍色的線也可以不用接到板子上
註:除NodeMCU板外,本篇的程式也都可使用在Wemos板子,Wemos的接線圖如下:
3.NodeMCU腳位圖
註:由上圖可知,有二組serial可用,分別是Serial(RXD0,TXD0)、Serial2(RXD2(GPIO13)、TXD2(GPIO15))
4.到Arduino IDE 寫程式
參考前一單元(01-G3+Uno)的程式,使用Serial2來連接G3,程式如下
#include <SoftwareSerial.h>
SoftwareSerial Serial2(13, 15); // RX2, TX2 ; D7,D8
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:
Serial.begin(9600);
Serial2.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
int count = 0;
unsigned char c;
unsigned char high;
while (Serial2.available()) {
c = Serial2.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");
}
else if(count == 7){
pmcf25 = 256*high + c;
Serial.print("CF=1, PM2.5=");
Serial.print(pmcf25);
Serial.println(" ug/m3");
}
else if(count == 9){
pmcf100 = 256*high + c;
Serial.print("CF=1, PM10=");
Serial.print(pmcf100);
Serial.println(" ug/m3");
}
else if(count == 11){
pmat10 = 256*high + c;
Serial.print("atmosphere, PM1.0=");
Serial.print(pmat10);
Serial.println(" ug/m3");
}
else if(count == 13){
pmat25 = 256*high + c;
Serial.print("atmosphere, PM2.5=");
Serial.print(pmat25);
Serial.println(" ug/m3");
}
else if(count == 15){
pmat100 = 256*high + c;
Serial.print("atmosphere, PM10=");
Serial.print(pmat100);
Serial.println(" ug/m3");
}
count++;
}
while(Serial2.available()) Serial2.read();
Serial.println();
delay(5000);
}
執行結果,一直出現check failed (初步的檢測資料就出問題),不知原因為何?如下:
為避免上面問題,直接改用Serial來傳送G3的數據,並使用LCD顯示器來顯示那6組數據~~
這邊的LCD顯示器的程式是利用 TUNIOT來寫再轉成Arduino語言(紅色字部分)
記得,上傳程式前,記得要把插在RX及TX的線先拔開,等程式上傳完畢後,再插上!
#include <SoftwareSerial.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F,16,2);
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:
lcd.begin();
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 (Serial.available()) {
c = Serial.read();
if((count==0 && c!=0x42) || (count==1 && c!=0x4d)){
Serial.println("check failed");
lcd.setCursor(0,0);
lcd.print(String("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");
lcd.clear();
lcd.setCursor(0,0);
lcd.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");
lcd.setCursor(8,0);
lcd.print(pmcf25 + String(","));
}
else if(count == 9){
pmcf100 = 256*high + c;
Serial.print("CF=1, PM10=");
Serial.print(pmcf100);
Serial.println(" ug/m3");
lcd.setCursor(12,0);
lcd.print(pmcf100);
}
else if(count == 11){
pmat10 = 256*high + c;
Serial.print("atmosphere, PM1.0=");
Serial.print(pmat10);
Serial.println(" ug/m3");
lcd.setCursor(0,1);
lcd.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");
lcd.setCursor(8,1);
lcd.print(pmat25 + String(","));
}
else if(count == 15){
pmat100 = 256*high + c;
Serial.print("atmosphere, PM10=");
Serial.print(pmat100);
Serial.println(" ug/m3");
lcd.setCursor(12,1);
lcd.print(pmat100);
}
count++;
}
while(Serial.available()) Serial.read();
Serial.println();
delay(5000);
}
好像成功了!
5.加入上網功能,並將PM2.5相關數據上傳到thingspeak
先上Thingspeak網站(https://thingspeak.com/)
Thingspeak的使用,請參考 01DHT11溫濕度
一樣利用TUNIOT來寫NodeMCU的網路功能及連上Thingspeak
再將上面程式轉為Arduino語言,請參考 02TUNIOT網路應用課程,有關網路的應用如下紅色字部分
本例是將大氣環境下的pm1.0、pm2.5、pm10的值,上傳到Thingspeak去
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
long pmcf10=0;
long pmcf25=0;
long pmcf100=0;
long pmat10=0;
long pmat25=0;
long pmat100=0;
char buf[50];
LiquidCrystal_I2C lcd(0x3F,16,2);
WiFiClient client;
String thingSpeakAddress= "http://api.thingspeak.com/update?";
String writeAPIKey;
String tsfield1Name;
String request_string;
HTTPClient http;
void setup()
{
lcd.begin();
Serial.begin(9600);
WiFi.disconnect();
delay(3000);
lcd.setCursor(0, 0);
lcd.print("START");
WiFi.begin("Xiaomi_6F5A","12345678");
while ((!(WiFi.status() == WL_CONNECTED))){
delay(300);
lcd.setCursor(0, 1);
lcd.print("......");
}
lcd.setCursor(0, 0);
lcd.print("I am connected!");
lcd.setCursor(0, 1);
lcd.print((WiFi.localIP()));
delay(1000);
}
void loop()
{
// put your main code here, to run repeatedly:
int count = 0;
unsigned char c;
unsigned char high;
while (Serial.available()) {
c = Serial.read();
if((count==0 && c!=0x42) || (count==1 && c!=0x4d)){
Serial.println("check failed");
lcd.setCursor(0,0);
lcd.print(String("check failed "));
break;
}
if(count > 15){
if (client.connect("api.thingspeak.com",80)) {
writeAPIKey = "key=P9K72NZ7VN7P7OF7";
tsfield1Name = "&field1=pmat10&field2=pmat25&field3=pmat100";
request_string = thingSpeakAddress;
request_string += "key=";
request_string += "P9K72NZ7VN7P7OF7";
request_string += "&";
request_string += "field1";
request_string += "=";
request_string += pmat10;
request_string += "&";
request_string += "field2";
request_string += "=";
request_string += pmat25;
request_string += "&";
request_string += "field3";
request_string += "=";
request_string += pmat100;
http.begin(request_string);
http.GET();
http.end();
}
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");
lcd.clear();
lcd.setCursor(0,0);
lcd.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");
lcd.setCursor(8,0);
lcd.print(pmcf25 + String(","));
}
else if(count == 9){
pmcf100 = 256*high + c;
Serial.print("CF=1, PM10=");
Serial.print(pmcf100);
Serial.println(" ug/m3");
lcd.setCursor(12,0);
lcd.print(pmcf100);
}
else if(count == 11){
pmat10 = 256*high + c;
Serial.print("atmosphere, PM1.0=");
Serial.print(pmat10);
Serial.println(" ug/m3");
lcd.setCursor(0,1);
lcd.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");
lcd.setCursor(8,1);
lcd.print(pmat25 + String(","));
}
else if(count == 15){
pmat100 = 256*high + c;
Serial.print("atmosphere, PM10=");
Serial.print(pmat100);
Serial.println(" ug/m3");
lcd.setCursor(12,1);
lcd.print(pmat100);
}
count++;
}
while(Serial.available()) Serial.read();
Serial.println();
delay(5000);
}
到Thingspeak網站觀看上傳結果https://thingspeak.com/channels/228017