一、功能简述
基于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 display
SoftwareSerial Serial2(8,9); //RX,TX
struct 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 3
int 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 5
int 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);
//串口显示-------------------------------------------------------------
}