01-G5+Uno
(2017/12/30)
俊青老師在好久前給我一個貴森森的PMS5003ST攀藤測PM2.5的感測器(也就是本篇文章的主角G5;這個感測器可以偵測PM2.5、甲醛及溫濕度的值),以前用G3接過Uno及NodeMCU控制板,今天再拿G5來重做一次試看看。
攀藤PMS5003ST-說明如附件
參考資料一:PMS5003ST arduino範例程式、https://sites.google.com/site/csjhmaker/e0/pan-tengpms5003
這個程式最簡單
這網站提供了arduino的程式,如下:
static unsigned int pm_cf_10; //定义全局变量
static unsigned int pm_cf_25;
static unsigned int pm_cf_100;
static unsigned int pm_at_10;
static unsigned int pm_at_25;
static unsigned int pm_at_100;
static unsigned int particulate03;
static unsigned int particulate05;
static unsigned int particulate10;
static unsigned int particulate25;
static unsigned int particulate50;
static unsigned int particulate100;
static float HCHO;
static float Temperature;
static float Humidity;
void getG5(unsigned char ucData)//获取G5的值
{
static unsigned int ucRxBuffer[250];
static unsigned int ucRxCnt = 0;
ucRxBuffer[ucRxCnt++] = ucData;
if (ucRxBuffer[0] != 0x42 && ucRxBuffer[1] != 0x4D)//数据头判断
{
ucRxCnt = 0;
return;
}
if (ucRxCnt > 38)//数据位判断//G5S为32,G5ST为38
{
pm_cf_10=(int)ucRxBuffer[4] * 256 + (int)ucRxBuffer[5]; //大气环境下PM2.5浓度计算
pm_cf_25=(int)ucRxBuffer[6] * 256 + (int)ucRxBuffer[7];
pm_cf_100=(int)ucRxBuffer[8] * 256 + (int)ucRxBuffer[9];
pm_at_10=(int)ucRxBuffer[10] * 256 + (int)ucRxBuffer[11];
pm_at_25=(int)ucRxBuffer[12] * 256 + (int)ucRxBuffer[13];
pm_at_100=(int)ucRxBuffer[14] * 256 + (int)ucRxBuffer[15];
particulate03=(int)ucRxBuffer[16] * 256 + (int)ucRxBuffer[17];
particulate05=(int)ucRxBuffer[18] * 256 + (int)ucRxBuffer[19];
particulate10=(int)ucRxBuffer[20] * 256 + (int)ucRxBuffer[21];
particulate25=(int)ucRxBuffer[22] * 256 + (int)ucRxBuffer[23];
particulate50=(int)ucRxBuffer[24] * 256 + (int)ucRxBuffer[25];
particulate100=(int)ucRxBuffer[26] * 256 + (int)ucRxBuffer[27];
HCHO=((int)ucRxBuffer[28] * 256 +(int)ucRxBuffer[29])/1000.000;
Temperature = ((int)ucRxBuffer[30] * 256 +(int)ucRxBuffer[31])/10.000;//包含温度
Humidity = ((int)ucRxBuffer[32] * 256 +(int)ucRxBuffer[33])/10.000;//包含湿度
if (pm_cf_25 > 999)//如果PM2.5数值>1000,返回重新计算
{
ucRxCnt = 0;
return;
}
ucRxCnt = 0;
return;
}
}
void setup() {
Serial.begin(9600);
}
void loop() {
while (Serial.available())
{
getG5(Serial.read());
}
Serial.print(" PM_CF1.0:");Serial.print(pm_cf_10);Serial.print(" ug/m3");//硬件串口输出数据
Serial.print(" PM_CF2.5:");Serial.print(pm_cf_25);Serial.print(" ug/m3");
Serial.print(" PM_CF10 :");Serial.print(pm_cf_100);Serial.println(" ug/m3");
Serial.print(" PM_AQI1.0:");Serial.print(pm_at_10);Serial.print(" ug/m3");
Serial.print(" PM_AQI2.5:");Serial.print(pm_at_25);Serial.print(" ug/m3");
Serial.print(" PM_AQI10:");Serial.print(pm_at_100);Serial.println(" ug/m3");
Serial.print(" PM_count03:");Serial.print(particulate03);Serial.print(" pcs/0.01cf");
Serial.print(" PM_count05:");Serial.print(particulate05);Serial.print(" pcs/0.01cf");
Serial.print(" PM_count10:");Serial.print(particulate10);Serial.print(" pcs/0.01cf");
Serial.print(" PM_count25:");Serial.print(particulate25);Serial.print(" pcs/0.01cf");
Serial.print(" PM_count100:");Serial.print(particulate100);Serial.println(" pcs/0.01cf");
Serial.print(" HCHO:");Serial.print(HCHO,3);Serial.println(" mg/m3");
Serial.print(" TS:");Serial.print(Temperature,1);Serial.println(" C"); //包含温度
Serial.print(" HS:");Serial.print(Humidity,1);Serial.println(" %RH"); //包含湿度
Serial.println("*********************************************");
delay(2000);
}
接線:(程式先燒錄好,再接上線),其實VCC要接5V的,TX RX都要TTL电平的(3.3V),但我沒有理會它,暫時不會,所以等以後再處理
結果:
參考資料二:https://github.com/keepworking/MECHA_PMS5003ST
將上面檔案下載,並將資料夾放到arduino/libraries下
開啟範例檔的ReadData
將G5的pin5(TXD)接到Arduino的D2
呈現結果
參考資料三:http://www.cnblogs.com/nightnine/p/6572891.html
程式:
參考資料四:打造属于自己的空气检测器(实现本地、home-assistant和homekit中显示)
====================================================================
加上 LCD 顯示器
利用以上程式可以得到PM1.0、PM2.5、PM10分別在CF=1為標準顆粒物、atmosphere為大氣環境下
CF=1 根据美国TSI公司的仪器校准
大气环境下 根据中国气象局的数据校准
從下面這資料,好像用大氣環境下的為主
首先,它可以採樣測定的空氣懸浮微粒有三種規格 0.3-1.0um/1.0-2.5um/2.5-10um,也就是說我們可以拿到 PM1.0/PM2.5/PM10 的測定資料(ug/m3)。而且PMS3003 的 datasheet 寫到他有兩套檢定空氣品質濃度的方法,分別是可以獲得「大氣環境下」和「標準顆粒物」兩組資料值,所以程式裡面每一次從 sensor 那邊得到的資料就會有2組,6個測定值。這裡我會在意的是「大氣環境下」測得的這組,所以,以下顯示的是大氣環境下這組的數據。
接線:
註:有關LCD顯示器的程式,採用Motoblockly的積木來產生(紅色字為增加的地方)
利用參考資料一的程式,再加上LCD的程式
#include <Wire.h>
#include <motoLiquidCrystal_I2C.h>
LiquidCrystal_I2C mylcd(0x3F,16,2); //注意是0x27或0x3F
static unsigned int pm_cf_10; //定义全局变量
static unsigned int pm_cf_25;
static unsigned int pm_cf_100;
static unsigned int pm_at_10;
static unsigned int pm_at_25;
static unsigned int pm_at_100;
static unsigned int particulate03;
static unsigned int particulate05;
static unsigned int particulate10;
static unsigned int particulate25;
static unsigned int particulate50;
static unsigned int particulate100;
static float HCHO;
static float Temperature;
static float Humidity;
void getG5(unsigned char ucData)//获取G5的值
{
static unsigned int ucRxBuffer[250];
static unsigned int ucRxCnt = 0;
ucRxBuffer[ucRxCnt++] = ucData;
if (ucRxBuffer[0] != 0x42 && ucRxBuffer[1] != 0x4D)//数据头判断
{
ucRxCnt = 0;
return;
}
if (ucRxCnt > 38)//数据位判断//G5S为32,G5ST为38
{
pm_cf_10=(int)ucRxBuffer[4] * 256 + (int)ucRxBuffer[5]; //大气环境下PM2.5浓度计算
pm_cf_25=(int)ucRxBuffer[6] * 256 + (int)ucRxBuffer[7];
pm_cf_100=(int)ucRxBuffer[8] * 256 + (int)ucRxBuffer[9];
pm_at_10=(int)ucRxBuffer[10] * 256 + (int)ucRxBuffer[11];
pm_at_25=(int)ucRxBuffer[12] * 256 + (int)ucRxBuffer[13];
pm_at_100=(int)ucRxBuffer[14] * 256 + (int)ucRxBuffer[15];
particulate03=(int)ucRxBuffer[16] * 256 + (int)ucRxBuffer[17];
particulate05=(int)ucRxBuffer[18] * 256 + (int)ucRxBuffer[19];
particulate10=(int)ucRxBuffer[20] * 256 + (int)ucRxBuffer[21];
particulate25=(int)ucRxBuffer[22] * 256 + (int)ucRxBuffer[23];
particulate50=(int)ucRxBuffer[24] * 256 + (int)ucRxBuffer[25];
particulate100=(int)ucRxBuffer[26] * 256 + (int)ucRxBuffer[27];
HCHO=((int)ucRxBuffer[28] * 256 +(int)ucRxBuffer[29])/1000.000;
Temperature = ((int)ucRxBuffer[30] * 256 +(int)ucRxBuffer[31])/10.000;//包含温度
Humidity = ((int)ucRxBuffer[32] * 256 +(int)ucRxBuffer[33])/10.000;//包含湿度
if (pm_cf_25 > 999)//如果PM2.5数值>1000,返回重新计算
{
ucRxCnt = 0;
return;
}
ucRxCnt = 0;
return;
}
}
void setup() {
Serial.begin(9600);
mylcd.init();
mylcd.backlight();
}
void loop() {
while (Serial.available())
{
getG5(Serial.read());
}
Serial.print(" PM_CF1.0:");Serial.print(pm_cf_10);Serial.print(" ug/m3");//硬件串口输出数据
Serial.print(" PM_CF2.5:");Serial.print(pm_cf_25);Serial.print(" ug/m3");
Serial.print(" PM_CF10 :");Serial.print(pm_cf_100);Serial.println(" ug/m3");
Serial.print(" PM_AQI1.0:");Serial.print(pm_at_10);Serial.print(" ug/m3");
Serial.print(" PM_AQI2.5:");Serial.print(pm_at_25);Serial.print(" ug/m3");
Serial.print(" PM_AQI10:");Serial.print(pm_at_100);Serial.println(" ug/m3");
Serial.print(" PM_count03:");Serial.print(particulate03);Serial.print(" pcs/0.01cf");
Serial.print(" PM_count05:");Serial.print(particulate05);Serial.print(" pcs/0.01cf");
Serial.print(" PM_count10:");Serial.print(particulate10);Serial.print(" pcs/0.01cf");
Serial.print(" PM_count25:");Serial.print(particulate25);Serial.print(" pcs/0.01cf");
Serial.print(" PM_count100:");Serial.print(particulate100);Serial.println(" pcs/0.01cf");
Serial.print(" HCHO:");Serial.print(HCHO,3);Serial.println(" mg/m3");
Serial.print(" TS:");Serial.print(Temperature,1);Serial.println(" C"); //包含温度
Serial.print(" HS:");Serial.print(Humidity,1);Serial.println(" %RH"); //包含湿度
Serial.println("*********************************************");
mylcd.setCursor(0,0);
mylcd.print(String("At ")+pm_at_10 + String(",")+pm_at_25 + String(",")+pm_at_100 );
mylcd.setCursor(0,1);
mylcd.print(String("F:")+HCHO + String(" T:")+Temperature + String(" H:")+Humidity );
delay(2000);
}