分享

自制PM25灰尘检测装置

 breezy 2015-04-27

PM2.5灰尘检测装置

灰尘检测

摘要:使用SHARP GP2Y1010灰尘传感器,通过Arduino控制读取灰尘数据,并增加DHT11可以同时进行温湿测量,可将结果显示在1602屏幕上,并可以通过串口接收数据。

缘起

由于近期关于PM2.5的概念比较热,本人也十分好奇到底目前日常的空气中有多少灰尘,另外对某些相关部门(这个部门能干任何事。。。)发布的数据的诚信度没有太多信心;于是谷歌了一下,果然,已经有牛人这么干过了。既然有了参考,那就自己做一个吧,算是造福草民了。所以文中的电路图、源代码可以随意转载使用,同时也公布了成本,大家任意DIY吧。如果有高富帅有专业的PM2.5传感器(例如Dylos DC1100),并愿意帮忙标定,可以在微博上联系我( @bunnybus ) 。

灰尘检测装置的核心是使用了灰尘传感器SHARP GP2Y1010,但是发现这个传感器只能够检测空气中的粉尘浓度,但是却不能判断是哪些粒子的粉尘浓度,比如是Pm10的还是Pm2.5的(不过目前看来,所有的灰尘都是有害的,区别只是是否能被人体排出)。

缺点是没有高精度的检测装置对公式作标定,但是从做的多个传感器的读数看来,还是比较稳定的。

检测标准

首先,灰尘读数参考国外空气的标准(我在日常环境没有读到过20以下,使用空气净化器之后降到过18以下)

开发过程

实际上,我参考的就是这两篇文章:

http://www./info/news_show/info_id/169993.html

http://www./arduino/airquality/

在具体的设计中,显示使用1602显示屏,增加了温湿度传感器DHT11,可以利用显示屏的其他空间,同时显示温度/湿度。

后来又写了个Windows App,可以通过串口获取数据,保存成CSV;之后可以在Excel中整理得到曲线:

PM25灰尘检测装置D13042301-PM25-SHARP-Dust-Sensor-0

做出来后发现身边有一些朋友对这个挺感兴趣,但是我手工焊线要4Hr以上(没办法,这个手艺无法速成),所以开始了设计电路板的工作(使用软件eagle),一次10个,想要的一人一个哈。

成本

外壳 —— 超市购买的小饭盒一个,5元(促销装)

SHARP GP2Y1010 —— 40元

1602显示屏幕 —— 8元

DHT11 —— 8元

Arduino pro mini —— 23元

TTL转USB模块 —— 4.4元 (如果不需要电脑监控数据,可以忽略)

电路板 —— 6元

接头、开关、电阻、电容、LED等

快递 —— 30元 (通常无法在同一家店买到所有器材,通常要从深圳的卖家买2~3家店)

软件和焊接——不算学习研究,大约耗时6~8Hr,我的工时单价不算低,就不列出来了。

硬件总成本100左右吧。

原理图

自制PM25灰尘检测装置

 

电路图解释:

PM25灰尘检测装置D13042301-PM25-SHARP-Dust-Sensor-2

印刷板图

PM25灰尘检测装置D13042301-PM25-SHARP-Dust-Sensor-3

自动布线

PM25灰尘检测装置D13042301-PM25-SHARP-Dust-Sensor-4

电路板成品照片(后面一个红色的是第一版):

PM25灰尘检测装置D13042301-PM25-SHARP-Dust-Sensor-5

可以看出,第一版的PCB设计的比较初级,线宽未设置,覆铜没有,电源的引脚画错、开关器件选择错误、可变电阻器件选择错误(器件太多了,随便选了个,造成引脚位置匹配不上);不过经过简单的手工处理还是可以用的,主体电路没问题。

以下是第二版的成品:

PM25灰尘检测装置D13042301-PM25-SHARP-Dust-Sensor-6

PM25灰尘检测装置D13042301-PM25-SHARP-Dust-Sensor-7

内部照片

PM25灰尘检测装置D13042301-PM25-SHARP-Dust-Sensor-8

电路板

PM25灰尘检测装置D13042301-PM25-SHARP-Dust-Sensor-9

灰尘传感器接线:

PM25灰尘检测装置D13042301-PM25-SHARP-Dust-Sensor-10

PM25灰尘检测装置D13042301-PM25-SHARP-Dust-Sensor-11

SHARP灰尘传感器的参考电路

PM25灰尘检测装置D13042301-PM25-SHARP-Dust-Sensor-12

DHT11温湿度传感器的参考电路

PM25灰尘检测装置D13042301-PM25-SHARP-Dust-Sensor-13

实际上,读取灰尘数据的核心源代码只有几行:

// ledPower is any digital pin on the arduino connected to Pin 3 on the sensor

digitalWrite(ledPower,LOW); // power on the LED

delayMicroseconds(delayTime);

dustVal=analogRead(dustPin); // read the dust value via pin 5 on the sensor

delayMicroseconds(delayTime2);

digitalWrite(ledPower,HIGH); // turn the LED off

delayMicroseconds(offTime);

源代码

由于我认为大家都了解当前环境的灰尘是件好事,所以公布源代码如下:

(说明:源代码没有整理过,比较粗燥,很简单的东西,我也不是软件高手,个人认为也不值得再折腾了)

//调用Arduino自带的LiquidCrystal库

#include

//温湿度传感器库,定义PM2.5污染指数级别

#include //调用Dht库

const int PM_LV_A = 5; //定义优质空气质量级别

const int PM_LV_B = 9; //定义良好空气质量级别

const int PM_LV_C = 30; //定义通常空气质量级别

const int PM_LV_D = 85; //定义轻度污染空气质量级别

//颗粒物传感器接口定义

const int dustPin=A1; //设置arduino模拟信号接口A1为pm2.5传感器采集口

int dustVal=0; //设置pm2.5传感器初始值

const int ledPower=2; //设置arduino数字信号接口2为pm2.5传感器LED发射口

int delayTime=280; //设置传感器延时

int delayTime2=40; //设置传感器延时

float offTime=9680; //设置pm2.5传感器采样时间

float pm25_val = 0; //设置pm2.5传感器初始值,0.5v电压相当于每立方米0.1mg颗粒物含量:0.1mg/m3

//LCD1602液晶屏接口对arduino端口定义,采用4bit传送,数据分别从D4、D5、D6、D7传输

const int RS = 3; //-------------

const int RW = 4; //-------------

const int EN = 5; //-------------

const int D4 = 6; //-------------数据分别从D4、D5、D6、D7传输

const int D5 = 7; //-------------

const int D6 = 8; //-------------

const int D7 = 9; //-------------

//设置LCD1602液晶接口

LiquidCrystal lcd(RS, RW, EN, D4, D5, D6, D7);

//快速刷新模式定义

const int FAST_REFRESH_MODE=10; //定义打开/关闭快速读取(最快3秒)的引脚:支持2种模式,即快速开关模式或者平均值模式

boolean FAST_REFRESH = true; //快速刷新模式(Off)

const int AVG_COUNTS = 10; //定义平均值模式每次平均采样次数,例如定义为10,即为每30s获取一次平均值(每3秒读一次)

//int pm_list[AVG_COUNTS]; //缓存数组(实际并未使用),可扩展为将历史数据记录在设备中供设备读取

int pm_list_sum; //平均值模式的累积合计变量

int pm_avg ; //PM25平均值

//DHT11温湿度传感器

dht DHT;

#define DHT11_PIN A0 //put the sensor in the digital pin 4 ——重新定义A0为获取DHT11的数据引脚(使用模拟量输入口,可以改为其它温度传感器,例如LM35)

//Arduino初始化函数setup()

void setup(){

Serial.begin(9600); //串口通讯速率9600

pinMode(ledPower,OUTPUT); //设置ledpower接都为信号输出

pinMode(4, OUTPUT); //设置arduino数字4口为输出端,此处作为10口(快速刷新模式)为开时亮灯

pinMode(FAST_REFRESH_MODE,INPUT); //设置arduino数字10口为输入端

lcd.begin(16, 2); //初始化LCD

//lcd.backlight(); //点亮LCD背光灯

delay(1000); //延时1000ms

pm_list_sum = 0; //初始化

}

//Arduino循环执行函数loop()

void loop(){

int pm25int = 0; //设置pm2.5初始值

//--get temperature and humdity

if (digitalRead(FAST_REFRESH_MODE) == HIGH) //PM2.5传感器控制程序

{

FAST_REFRESH = true;

}

else

{

FAST_REFRESH = false;

}

int chk = DHT.read11(DHT11_PIN);

switch (chk) //检测数值串口输出信息

{

case 0: Serial.print("OK,\t"); //如果数据为0,串口输出采集正常。

break;

case -1: Serial.print("Checksum error,\t"); //如果数据为-1,串口输出--错误。

break;

case -2: Serial.print("Time out error,\t"); //如果数据为0,串口输出时间溢出。

break;

default: Serial.print("Unknown error,\t"); //串口输出未知错误。

break;

}

//-------------------------------------------------------------------------------

if (!FAST_REFRESH)

{

pm_list_sum = 0; //---------------

pm_avg = 0; //---------------

for(int i=0;i<AVG_COUNTS;i++)

{

// ledPower is any digital pin on the arduino connected to Pin 3 on the sensor

digitalWrite(ledPower,LOW); //接通颗粒物传感器led灯电源

delayMicroseconds(delayTime); //延时

dustVal=analogRead(dustPin); //读取颗粒物传感器第五模拟口电压数值

delayMicroseconds(delayTime2); //延时

digitalWrite(ledPower,HIGH); //关闭颗粒物传感器led灯电源

delayMicroseconds(offTime); //延时

pm25_val = dustVal * 0.83984375 - 99.9 ; //计算pm2.5采集数值

int pm25int = dustVal * 0.83984375 - 99.9 ; //------------------

if (pm25int < 0) //------------------

{

pm25int = 20; //给Pm2.5int变量赋初始值

}

pm_list_sum = pm_list_sum + pm25int; //------------------

delay(3000); //延时3000ms

}

pm_avg = pm_list_sum / AVG_COUNTS; //计算pm2.5数据平均值

}

else

{

// 颗粒物传感器LED电源引脚接在arduino的第D3接口

digitalWrite(ledPower,LOW); //接通颗粒物传感器led灯电源

delayMicroseconds(delayTime); //延时

dustVal=analogRead(dustPin); //读取颗粒物传感器第五模拟口电压数值

delayMicroseconds(delayTime2); //延时

digitalWrite(ledPower,HIGH); //关闭颗粒物传感器led灯电源

delayMicroseconds(offTime); //延时

pm25_val = dustVal * 0.83984375 - 99.9 ; //------------------

pm25int = dustVal * 0.83984375 - 99.9 ; //------------------

delay(3000); //延时3000ms

}

if (!FAST_REFRESH)

{

Serial.print("Temperature:"); //串口发送“Temperature:”字符

Serial.print(DHT.temperature); //串口发送温度数值

Serial.print("[C]"); //串口发送“[C]”字符

Serial.print(","); //串口发送“,”字符

Serial.print("Humdity:"); //串口发送“Humdity:”字符

Serial.print(DHT.humidity); //串口发送湿度数值

Serial.print("%"); //串口发送“%”字符

Serial.print(","); //串口发送“,”字符

Serial.print("PM25:"); //串口发送“PM25:”字符

Serial.print(pm25_val); //串口发送PM2.5数值

Serial.println(pm_avg); //串口发送PM2.5平均

Serial.println("[ug/m3]"); //串口发送“[ug/m3]”字符

//LCD液晶显示信息

lcd.clear(); //LCD1602液晶清屏

lcd.setCursor(0,0); //设置LCD1602光标在第一行第一格

lcd.print("D="); //LCD1602输出“D=”

lcd.print(pm_avg); //LCD1602输出PM2.5平均采样值

lcd.print(" ug/m3"); //LCD1602输出“D=”

//选择输出空气污染指数级别

if (PM_LV_A > pm_avg) //判断采集的平均值是否小于污染A级别

lcd.print(" Fine"); //LCD1602输出优信息

else if (PM_LV_B > pm_avg) //判断采集的平均值是否小于污染D级别

lcd.print(" Good"); //LCD1602输出好信息

else if (PM_LV_C > pm_avg) //判断采集的平均值是否小于污染C级别

lcd.print(" Normal"); //LCD1602输出良信息

else if (PM_LV_D > pm_avg) //判断采集的平均值是否小于污染D级别

lcd.print(" Bad"); //LCD1602输出轻度污染信息

else

lcd.print(" Hell"); //LCD1602输出重度污染信息

//LCD液晶显示信息

lcd.setCursor(0,1); //设置光标在第二行第一格

lcd.print("Tmp:"); //LCD1602输出“Tmp:”字符

lcd.print(DHT.temperature); //LCD1602输出温度值

lcd.print("C"); //LCD1602输出“C”字符

lcd.print(" "); //LCD1602输出“ ”字符

lcd.print("Hum:"); //LCD1602输出“Hum:”字符

lcd.print(DHT.humidity); //LCD1602输出湿度值

lcd.print("%"); //LCD1602输出“%字符

}

else

{

// 串口发送数据

Serial.print("Temperature:"); //串口发送“Temperature:”字符

Serial.print(DHT.temperature); //串口发送温度数值

Serial.print("[C]"); //串口发送“[c]”字符

Serial.print(","); //串口发送“,”字符

Serial.print("Humdity:"); //串口发送“Humdity:”字符

Serial.print(DHT.humidity); //串口发送湿度数值

Serial.print("%"); //串口发送“%”字符

Serial.print(","); //串口发送“,”字符

Serial.print("PM25:"); //串口发送“PM25:”字符

Serial.print(pm25_val); //串口发送pm2.5数值

Serial.println("[ug/m3]"); //串口发送“[ug/m3]”字符并换行

//LCD1602液晶显示信息

lcd.clear(); //LCD1602液晶清屏

lcd.setCursor(0,0); //设置光标显示在第一行第一格

lcd.print("D="); //输出“D=”字符

lcd.print(pm25int); //输出pm2.5数值

lcd.print(" ug/m3"); //输出“ ug/m3”字符

//选择输出空气污染指数级别

if (PM_LV_A > pm_avg) //判断采集的平均值是否小于污染A级别

lcd.print(" Fine"); //LCD1602输出优信息

else if (PM_LV_B > pm_avg) //判断采集的平均值是否小于污染B级别

lcd.print(" Good"); //LCD1602输出好信息

else if (PM_LV_C > pm_avg) //判断采集的平均值是否小于污染C级别

lcd.print(" Normal"); //LCD1602输出良信息

else if (PM_LV_D > pm_avg) //判断采集的平均值是否小于污染D级别

lcd.print(" Bad"); //LCD1602输出轻度污染信息

else

lcd.print(" Hell"); //LCD1602输出重度污染信息

//LCD1602液晶显示信息

lcd.setCursor(0,1); //设置光标显示在第二行第一格

lcd.print("Tmp:"); //LCD1602输出“Tmp:”字符

lcd.print(DHT.temperature); //LCD1602输出温度数值

lcd.print("C"); //LCD1602输出“C”字符

lcd.print(" "); //LCD1602输出“ ”字符

lcd.print("Hum:"); //LCD1602输出“Hum:”字符

lcd.print(DHT.humidity); //LCD1602输出“DHT.humidity”字符

lcd.print("%"); //LCD1602输出“%”字符

}

}

关键词 : 灰尘,传感器,PM2.5,DIY
标签 : 灰尘,传感器,PM2.5,DIY

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多