【应用实例】单片机PM2.5空气监测仪--攀藤G5激光PM2.5传感器

来源:互联网 发布:叫爸爸是什么意思网络 编辑:程序博客网 时间:2024/04/28 07:26

一、功能简述

基于Arduino控制,利用攀藤G5激光传感器测量PM值,DHT11温湿度传感器测量温湿度,1602LCD显示数据。外接一个继电器,当达到一定污染值时启动净化风扇。

焊接之后大概是这个样子。

这里写图片描述

二、元件

Arduino uno

攀藤G5激光PM2.5传感器

这里写图片描述

DHT11温湿度传感器

DHT11便宜,但是精度较低,可以用DHT22试试

这里写图片描述

1602LCD液晶屏

I2C转接板

继电器

三、测试G5传感器

攀藤G5传感器能测量12个数据,包括PM1.0、PM2.5、PM10浓度和颗粒个数。

下图是传感器的管脚定义和接线方式:

这里写图片描述

将传感器用USB转TTL下载线于电脑连接

先串口测试返回的数据,在串口软件中进行如下设置:

这里写图片描述

窗口中返回的每一行即是测量的结果,下图是各个数据对应的测量量,比如大气中PM2.5的浓度对应返回数据的第12和13位,程序中对这两位进行提取。

这里写图片描述

四、电路连接

1.G5激光PM2.5传感器

pin1- ->VCC(+5V)
pin2- ->GND
pin5- ->软串口RX(我这里定义的是pin8)

2.DHT11温湿度传感器

pin1- ->GND
pin3- ->pin4
pin4- ->VCC(+5V)
pin3外接5K欧电阻接VCC

3.1602LCD屏

16引脚的1602与I2C转接口相连,I2C转接口有四个引脚
GND- ->GND
VCC- ->VCC
SDA- ->A4
SCL- ->A5

4.继电器

IN- ->pin12
GND- ->GND
VCC- ->VCC

电路图

这里写图片描述

实物接线图

这里写图片描述

五、程序

#include <dht11.h>              //温度传感器dht11库文件#include <Wire.h>#include <SoftwareSerial.h>     //软串口库文件#include <LiquidCrystal_I2C.h>   LiquidCrystal_I2C lcd(0x27, 16, 2);  // set the LCD address to 0x27 for a 16 chars and 2 line displaySoftwareSerial Serial2(8,9);   //RX,TXstruct PARAMS {    float T;//显示温度    float H;//显示湿度    long P1_0;  //显示PM1.0    long _P1_0;    long P2_5;  //显示PM2.5    long _P2_5;    long P10;   //显示PM10    long _P10;      //unsigned long _K1;    //颗粒物浓度    //unsigned long K1;    long _K2;    long K2;    long _K3;    long K3;    long _K4;    long K4;    long _K5;    long K5;    //long _K6;    //long K6;} _params;         //结构体//对温湿度传感器参数设置dht11 HT;   // 现在 HT 代表 DHT11 传感器const int pin = 3;  // 把 DHT11 的 data pin 連到 arduino Pin 3int jidianqi = 12;  //设置继电器的控制数字引脚//初始化void setup(){    lcd.begin();                      lcd.backlight();    lcd.setCursor(0,0);    lcd.print("    Welcome!");  //屏幕设置    delay(1500);    lcd.setCursor(0,1);    lcd.print(" PM2.5 Detector");       delay(1500);    Serial.begin(9600);            Serial2.begin(9600);        //软串口    pinMode(jidianqi,OUTPUT);   //继电器引脚为输出模式}//G5 相关变量static unsigned char ucRxBuffer[250];static unsigned char ucRxCnt = 0;//循环计数器unsigned char loopCnt = 0;//获取PM2.5的值void getPM25(unsigned char ucData) {    ucRxBuffer[ucRxCnt++] = ucData;    if (ucRxBuffer[0] != 0x42 && ucRxBuffer[1] != 0x4D)      {        ucRxCnt = 0;    }    if (ucRxCnt > 31)     {        //_params._P2_5 = (float)ucRxBuffer[6] * 256 + (float)ucRxBuffer[7]; //美国标准        _params._P1_0 = (float)ucRxBuffer[10] * 256 + (float)ucRxBuffer[11]; //中国标准     *****获取*****        _params._P2_5 = (float)ucRxBuffer[12] * 256 + (float)ucRxBuffer[13];         _params._P10 = (float)ucRxBuffer[14] * 256 + (float)ucRxBuffer[15];         //_params._K1  = (float)ucRxBuffer[16] * 256 + (float)ucRxBuffer[17];         _params._K2  = (float)ucRxBuffer[18] * 256 + (float)ucRxBuffer[19];         _params._K3  = (float)ucRxBuffer[20] * 256 + (float)ucRxBuffer[21];         _params._K4  = (float)ucRxBuffer[22] * 256 + (float)ucRxBuffer[23];         //_params._K5  = (float)ucRxBuffer[24] * 256 + (float)ucRxBuffer[25];         //_params._K6  = (float)ucRxBuffer[26] * 256 + (float)ucRxBuffer[27];         ucRxCnt = 0;    }}//中位值平均滤波,处理PM2.5的值#define FILTER_N 5int Filter(long p) {             //函数Filter对PM2.5数据进行处理    int i;    int filter_sum = 0;    int filter_max, filter_min;    int filter_buf[FILTER_N];    for (i = 0; i < FILTER_N; i++)     {        filter_buf[i] = p;     //处理的数据是_params._P        delay(1);    }    filter_max = filter_buf[0];    filter_min = filter_buf[0];    filter_sum = filter_buf[0];    for (i = FILTER_N - 1; i > 0; i--)     {        if (filter_buf[i] > filter_max)            filter_max = filter_buf[i];        else if (filter_buf[i] < filter_min)            filter_min = filter_buf[i];        filter_sum = filter_sum + filter_buf[i];        filter_buf[i] = filter_buf[i - 1];    }    i = FILTER_N - 2;    filter_sum = filter_sum - filter_max - filter_min + i / 2; // +i/2 的目的是为了四舍五入    filter_sum = filter_sum / i;    return filter_sum;}void loop() {    while (Serial2.available())       {        getPM25(Serial2.read());     //通过getPM25函数获取数据    }    //DHT11更新数据速度很慢,所以不要读的那么快    if (loopCnt % 50 == 0)     {        HT.read(pin);  // 读取 DHT11 传感器        _params.P1_0 = Filter(_params._P1_0);        //通过Filter函数滤波处理数据赋给_params.P        _params.P2_5 = Filter(_params._P2_5);                _params.P10 = Filter(_params._P10);            //_params.K1 = Filter(_params._K1);          _params.K2 = Filter(_params._K2);          _params.K3 = Filter(_params._K3);          _params.K4 = Filter(_params._K4);          //_params.K5 = Filter(_params._K5);          //_params.K6 = Filter(_params._K6);         //1602显示-------------------------------------------------------------        //lcd.begin();                          //lcd.backlight();        lcd.setCursor(0,0);        lcd.print(String("") + " H:"+ HT.humidity + " %");      //打印温湿度数值        lcd.print(String("")+"  T:"+ HT.temperature +"'C");         lcd.setCursor(0,1);        lcd.print(String("") + " PM2.5:"+_params.P2_5+ " ug/m3 ");    //打印PM2.5数值        //1602显示-------------------------------------------------------------    }    if (++loopCnt > 99)     {        loopCnt = 0;    }    if(_params.P2_5<100)                    {        digitalWrite(12,HIGH);    }    else                        //当PM2.5的值大于100时,启动继电器(带动净化风扇工作)        digitalWrite(12,LOW);    //串口显示-------------------------------------------------------------    Serial.print(String("") + "Humidity = "+ HT.humidity + " %");    Serial.println(String("")+", temperature = "+ HT.temperature +" °C");    Serial.println(_params.P1_0);    Serial.println(_params.P2_5);    Serial.println(_params.P10);    //Serial.println(_params.K1);    Serial.println(_params.K2);    Serial.println(_params.K3);    Serial.println(_params.K4);    //Serial.println(_params.K5);    //Serial.println(_params.K6);    //串口显示-------------------------------------------------------------}
原创粉丝点击