如何自己动手制作一个靠谱的PM2.5检测仪

气象专家和医学专家认为,由细颗粒物造成的灰霾天气对人体健康的危害甚至要比沙尘暴更大。粒径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(freebuf)

原文发表时间:2018-03-19

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏牛客网

京东Java岗面经

16300
来自专栏逍遥剑客的游戏开发

PhysX学习笔记(3): 动力学(2) Actor

21020
来自专栏Crossin的编程教室

【每周一坑】囚徒困境

本周的题目非常有意思,取于大名鼎鼎的 囚徒困境 。首先来看背景资料: “囚徒困境”是1950年美国兰德公司的梅里尔·弗勒德(Merrill Flood)和梅尔文...

40080
来自专栏程序人生

谈谈FRP和Observable(一)

Observable是方兴未艾的FRP(Functional Reactive Programming)革命里最引人注目的一把火炬。FRP发展了也有两年多了,至...

49370
来自专栏数据结构与算法

10.31NOIP模拟赛解题报告

8410
来自专栏Crossin的编程教室

【每周一坑】图像的指纹:数字水印 + 【解答】鸡兔同笼

曾经有过这样的新闻:某公司的员工将内网论坛上的言论截屏发布到互联网上,引发了热议。于是公司通过截图定位到了员工的身份,将其开除。

21020
来自专栏企鹅号快讯

数据分析:寻找Python最优计算性能

1、场景描述 在数据统计分析过程中,求累计值(总和)是最常用的统计指标之一,市面上的各种流行数据库均支持的查询方式基本如下: select sum(c) fro...

23070
来自专栏PPV课数据科学社区

【完整案例】如何用R实现空间数据可视化

image.png 流行病学的数据讲究“三间分布”,即人群分布、时间分布和空间分布。其中的“空间分布”最好是在地图上展示,才比较清楚。R软件集统计分析与高级...

1.2K70
来自专栏Crossin的编程教室

我在Python的艳阳里,大雪纷飞

你在南方的艳阳里大雪纷飞;我在北方的寒夜里四季如春。 昨天,南方不少地区,尤其是长江中下游一带迎来了一场难得的大雪。虽说给出行带来极大的不便,但也让我们这些没怎...

295110
来自专栏数据魔术师

运筹学教学|修正单纯形法(revised simplex algorithm)代码分享及详细注释

欢声笑语中,小编学会了单纯形法,心里还有点小傲骄!!准备晚上去PUBG里面潇洒一把~ ? 然而,老板突然来电话说,单纯形法有升级的版本!需要我赶紧准备一份代码。...

91470

扫码关注云+社区

领取腾讯云代金券