*本文作者:_橙子 ゝ,本文属 FreeBuf 原创奖励计划,未经许可禁止转载。
气象专家和医学专家认为,由细颗粒物造成的灰霾天气对人体健康的危害甚至要比沙尘暴更大。粒径10微米以上的颗粒物,会被挡在人的鼻子外面;粒径在2.5微米至10微米之间的颗粒物,能够进入上呼吸道,但部分可通过痰液等排出体外,另外也会被鼻腔内部的绒毛阻挡,对人体健康危害相对较小;而粒径在2.5微米以 下的细颗粒物,直径相当于人类头发的1/10大小,不易被阻挡。被吸入人体后会直接进入支气管,干扰肺部的气体交换,引发包括哮喘、支气管炎和心血管病等方面的疾病。当前社会,身体健康问题已经越来越受到人们的重视。
网上买一个PM2.5需要好几百,太贵了,贫穷限制了我的想象,刚好最近国内Micropython火的不行,从网上发现了一个Micropython的开发板——TPYBoard,正好用Micropython编辑,我就自己动手做了一个简单的PM2.5检测仪,妈妈再也不用担心我的健康啦。下面我带大家自己动手制作一个简单精确的pm2.5检测仪。
材料准备
PM2.5粉尘传感器1个
TPYBoard v102开发板1块
5110显示屏或者oled显示屏1块
杜邦线若干
TPYBoard v102
PM2.5粉尘传感器工作原理
PM2.5粉尘传感器
PM2.5粉尘传感器的工作原理是根据光的散射原理来开发的,微粒和分子在光的照射下会产生光的散射现象,与此同时,还吸收部分照射光的能量。
当一束平行单色光入射到被测颗粒场时,会受到颗粒周围散射和吸收的影响,光强将被衰减。如此一来便可求得入射光通过待测浓度场的相对衰减率。而相对衰减率的大小基本上能线性反应待测场灰尘的相对浓度。光强的大小和经光电转换的电信号强弱成正比,通过测得电信号就可以求得相对衰减率,进而就可以测定待测场里灰尘的浓度。在传感器的中间有一个洞,这个洞可以让空气在里面流通。在洞的两个边缘 ,一面安装有一个激光发射器,另一面安装有激光接收器。这样一来,空气流过这个小洞,空气里的颗粒物呢就会挡住激光,从而产生散射,另一面的接收器,是依据接收到的激光强度来发出不同的信号的(其实就是输出不同的电压值)。这样一来,空气里的颗粒物越多,输出的电压越高,颗粒物越少,输出的电压越低。
内部结构如图内部结构仿真图所示:
PM2.5粉尘传感器传感器数据处理
上面说了传感器的原理,接下来就说说它传出来的信号和对于接收到的信号的计算吧。
这个传感器的输出数据是靠串口进行传输的,传感器会通过串口每10ms不到(一般3~4ms)发送一个数据,数据的类型大致是个“0X00”这样的16进制的数据。每次的数据会以“0XAA”作为起始端,以“0XFF”作为结束端。共7个数据位,7个数据位中包含了起始位,结束位,数据高位,数据低位,数据高校验位,数据低校验位和校验位(校验位是怎样计算出来的,下面会讲到)。数据格式大致如下:
其中校验位长度=Vout(H)+Vout(L)+Vref(H)+Vref(L)的长度。
数据的组成一共是有7个数据位,但是只有Vout(H)和Vout(L)这两个数据才是我们真正所需要的。我们需要依照这两个数据算出来串口输出的数字数据,从而通过数模转换公式来计算出输出的电压。进一步的通过比例系数计算出空气中颗粒物的数量。下面来说一下怎么计算。
传感器输出的数据分为高位和低位,其中呢Vout(H)为高位,Vout(L)为低位。因为串口传进来的Vout(H)和Vout(L)是16进制的,第一步先转化成10进制的(这个大家都会,不多说了)。然后根据这两个输出值的10进制数计算出串口输出数值的电压。
公式如下(其中Vout(H)和Vout(L)是已转化为10进制的):
Vout=(Vout(H)*256+Vout(L))/1024*5
这样就算出来了他输出出来的电压了,再根据比例系数A,就可以计算出空气中的颗粒物的值了。(A的值一般是在800到1000,具体的数值还要根据你买到的传感器的精度,准确度和误差值进行确定。我现在用的是800。)
PM2.5检测仪整体接线方法
下面我们将PM2.5粉尘传感器和5110显示屏与PTYBoard连接起来:
硬件接线图
5110显示屏 | TPYBOAR | PM2.5粉尘传感器 |
---|---|---|
RST | Y10 | |
CE | Y11 | |
DC | Y9 | |
DIN | X8 | |
CLK | X6 | |
VCC | 3v3 | |
BL | Y12 | |
GND | GND | |
X4 | RX | |
VIN | VCC | |
GND | GND |
运行测试
接线ok后,导入font.py文件和upcd8544.py文件(主要用于驱动5110显示数据),可以到
http://www.tpyboard.com/support/studyexample14/206.html下载来用,再运行main.py即可看到当前的空气质量等级以及PM2.5的浓度值了。
下面链接是我用烟熏的演示视频,供大家参考一下:
看不到?点这里
源代码
这是main.py的主程序代码,可以直接复制使用
# main.py -- put your code here!
#main.py
import pyb
import upcd8544
from machine import SPI,Pin
from pyb import UART
from ubinascii import hexlify
from ubinascii import *
leds = [pyb.LED(i) for i in range(1,5)]
P,L,SHUCHU=0,0,0
#A比例系数,在北方一般使用800-1000.南方空气好一些,一般使用600-800.这个还和你使用的传感器灵敏度有关的,需要自己测试再定下来
A=800
#G为固定系数,是为了把串口收到的数据转换成PM标准值
G=1024/5
SPI = pyb.SPI(1) #DIN=>X8-MOSI/CLK=>X6-SCK
#DIN =>SPI(1).MOSI 'X8' data flow (Master out, Slave in)
#CLK =>SPI(1).SCK 'X6' SPI clock
RST = pyb.Pin('Y10')
CE = pyb.Pin('Y11')
DC = pyb.Pin('Y9')
LIGHT = pyb.Pin('Y12')
lcd_5110 = upcd8544.PCD8544(SPI, RST, CE, DC, LIGHT)
u2 = UART(2, 2400)
count_=0
def ChangeLEDState(num_):
global leds
len_=len(leds)
for i in range( 0,len_):
if i!=num_:
leds[i].off()
else:
leds[i].on()
while True:
u2.init(2400, bits=8 , parity=None, stop=1)
pyb.delay(80)
Quality='DATA NULL'
if(u2.any()>0 ):
u2.deinit()
_dataRead=u2.readall()
#R代表截取数据的起始位
R=_dataRead.find(b'\xaa' )
#R>-1代表存在起始位,长度大于起始位位置+2
if R>-1 and len(_dataRead)>(R+2):
P=_dataRead[R+ 1]
L=_dataRead[R+ 2]
#把串口收到的十六进制数据转换成十进制
SHI=P* 256+L
SHUCHU=SHI/ G*A
if(SHUCHU<35):
Quality = 'Excellente'
print('环境质量:优', 'PM2.5=',SHUCHU)
count_=1
elif(35<SHUCHU< 75):
Quality = 'Good'
print('环境质量:良好', 'PM2.5=',SHUCHU)
count_=1
elif(75<SHUCHU< 115):
Quality = 'Slightly-polluted'
print('环境质量:轻度污染 ', 'PM2.5=',SHUCHU)
count_=3
elif(115<SHUCHU< 150):
Quality = 'Medium pollution'
print('环境质量:中度污染 ', 'PM2.5=',SHUCHU)
count_=2
elif(150<SHUCHU< 250):
Quality = 'Heavy pollution'
print('环境质量:重度污染 ', 'PM2.5=',SHUCHU)
count_=0
elif(250<SHUCHU):
Quality = 'Serious pollution'
print('环境质量:严重污染 ', 'PM2.5=',SHUCHU)
count_=0
ChangeLEDState(count_)
lcd_5110.lcd_write_string('AQI Level',0, 0)
lcd_5110.lcd_write_string(str(Quality),0, 1)
lcd_5110.lcd_write_string('PM2.5:',0, 2)
lcd_5110.lcd_write_string(str(SHUCHU),0, 3)
*本文作者:_橙子 ゝ,本文属 FreeBuf 原创奖励计划,未经许可禁止转载。