當前位置:
首頁 > 新聞 > 如何自己動手製作一個靠譜的PM2.5檢測儀

如何自己動手製作一個靠譜的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 原創獎勵計劃,未經許可禁止轉載。


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 FreeBuf 的精彩文章:

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

TAG:FreeBuf |