如何自己動手製作一個靠譜的PM2.5檢測儀
*本文作者:_橙子 ゝ,本文屬 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 原創獎勵計劃,未經許可禁止轉載。


※部分B站帳號被發現可直接登錄360快視頻,疑似資料庫泄漏
※前端黑魔法之遠程控制地址欄
TAG:FreeBuf |