學習目標 : 認識faya灰塵感應模組的功能及使用方式
學習時間 : 40min
示範模組 : (1) faya brickNano
(2) 灰塵感應模組
工具 : (1) 樂高積木底板 (相容)
====================功能介紹====================
faya灰塵感應模組採用了夏普公司(Sharp)的第三代灰塵感應器(GP2Y1051),第一代的感應器以類比電壓的形式輸出,使用者須自行套用公式計算粉塵濃度,第二代改進成以串列訊號輸出,但必須扣除無塵電壓,最新的一代更改了內部演算法,只需將輸出粉塵參數套入公式後,就可推算環境粉塵濃度。
感測器如上圖所示,利用一訊號線TXD即可進行資料的接收,感測器的串列傳輸協定以2400鮑率進行傳輸。當感測器接上5V電源後,會在TXD埠持續輸出粉塵參數,每10ms發送一個字節,總共七個字節,數據發送格式為:
其中校驗位 = Vout(H)+Vout(L)+Vref(H)+Vref(L)
有了以上粉塵參數,我們可以依照Datasheet的說明,套入公式算的粉塵濃度
其中 Vout為透過粉塵參數所計算出的輸出信號
A為比例係數,用來調整輸出電壓與濃度間的關係,官方Datasheet中提供不同條件測試下的資料如下圖,由圖中可看出比例係數A = Ud / Vout 分別為500和280,大家可以參考此數據設定比例係數A
如果我們將A取平均 = (500+280)/2 = 390
Vout 利用上述表格套入公式 = (2x256 + 157) *5 / 1024 = 3.26V
粉塵濃度 = 3.26 * 390 = 390 ug/m3 ...屬於嚴重汙染等級的懸浮微粒
對於粉塵的詳細說明,大家可參考Wiki的連結解釋
對於感測器的Datasheet,大家從這邊下載
====================原理知識====================
以下解釋提供給有需要知道背後原理的人:
faya灰塵應模組的電路圖如下,基本上只用到VCC / GND / TXD三隻腳位,並拉出到PCB板子上,注意到由於感測器屬於主動傳輸資料,並無接收資料或指令的功能,因此只使用到TXD埠,將此埠連接到MCU的RXD埠即可接收資料 (2400bps)
===================範例實作(1)===================
了解模組功能(原理)後,我們用以下範例來展示模組的功能:
目標:
(1)每0.5秒在Arduino Serial Monitor秀出目前的粉塵濃度
接線:
(1) 電源線連接
如下圖所示,連接的說明請看這篇文章 或簡易版
(2) 訊號線連接
Arduino_D10 ===> 灰塵感應器_TXD
範例程式:
本次的範例程式,我們直接拿網路上署名Weesky維天監製的作者所提供的範例,稍作修改後並詳細解釋
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 2018/10/19 | |
// Faya-Nugget 範例程式 (Dust_Sensor_1.ino) | |
// 單元: 模組介紹:faya灰塵感應模組 | |
// 網址: https://fayalab.blogspot.com/2018/10/dust-Sensor.html | |
// 目標: (1) 灰塵感應模組每0.5秒送出 xxxxxxxxxxxxxxxxxxxxxxx | |
// 接線: Arduino ==> faya模組 | |
// D10 ==> TxD (灰塵感應模組) | |
//====================== 原始檔案資訊 ====================== | |
// Arduino夏普GP2Y1051AU0F的串口讀取_源代碼_Weesky維天監製 | |
// 作者ID:Weesky ; ... | |
// 2014年11月23日 | |
// v1.0 基礎版本,成功讀取數值,並且算出PM2.5濃度。 | |
// v1.1 改進了算法,這樣看起來數值高了些。對於愛好者操作更容易了。 | |
//請不要在採樣週期裡面添加延遲delay這樣的。不然串口寄存器只有64Byte,很可能被塞滿。 | |
//========================================================== | |
#include<SoftwareSerial.h> // 引入SoftwareSerial軟體模擬串列埠函式庫 | |
int incomeByte[7]; //儲存七個字節的資料 | |
int data; //暫存每個字節的資料 | |
int z=0; // 字節計數器 數據傳輸共7字節 (0~6) | |
int sum; // 校驗位 = 第1~第4字節的總和 = Vout(H)+Vout(L)+Vref(H)+Vref(L) | |
int A = 390; // A = 比例係數 (280~500間) | |
const int TX = 11; // 灰塵感測模組沒有RX腳,但需要設一個沒有用的腳位讓程式順利組譯 | |
const int RX = 10; // 灰塵感測模組 TxD 接到Arduino第10腳 | |
SoftwareSerial fayaSerial(RX, TX); //定義Arduino連接到藍芽模組的串列腳位 | |
void setup() | |
{ | |
Serial.begin(9600); // Arduino串列埠baudRate = 9600 | |
fayaSerial.begin(2400); // 軟體模擬串列埠baudRate = 2400 | |
} | |
void loop(){ | |
while (fayaSerial.available()>0) | |
{ | |
data=fayaSerial.read(); | |
if(data == 170) // 170 = 0xaa, 起始字節 | |
{ | |
z=0; // 字節計數歸零 | |
incomeByte[z]=data; // 將data存到第0個字節(0Xaa) | |
} | |
else | |
{ | |
z++; | |
incomeByte[z]=data; // 依序儲存第1字節到第6字節的資料 | |
} | |
if(z==6) //儲存完七個字節後 | |
{ | |
sum=incomeByte[1]+ incomeByte[2]+ incomeByte[3] + incomeByte[4]; //加總字節1~4 | |
if(incomeByte[5]==sum && incomeByte[6]==255 ) //比對加總後是否和字節5(校驗位)相同,並且字節6是否為結束位元 0xff | |
{ | |
Serial.print("Data OK! |"); // 完成6個字節的儲存 | |
for(int k=0;k<7;k++) //印出七個字節 | |
{ | |
Serial.print(incomeByte[k]); // 起始位 | Vout(H) | Vout(L) | Vref(H) | Vref(L) | 校驗位 | 結束位 | |
Serial.print("|"); // 0xaa | 0x?? | 0x?? | 0x?? | 0x?? | sum | 0xff | |
} | |
Serial.print(" Vo="); | |
//感測器輸出電壓 = ((Vout(H) x 256 + Vout(L)) / 1024) x 5 | |
float Vout=(incomeByte[1]*256.0+incomeByte[2])*5/1024.0; | |
Serial.print(Vout,3); // Vout取到小數第3位 | |
Serial.print("v | "); | |
float Ud=Vout*A; //粉塵濃度 Ud= Vout x A | |
Serial.print(" PM2.5 = "); | |
Serial.print(Ud,2); // Ud取到小數第2位 | |
Serial.print("ug/m3 "); | |
Serial.println(); | |
delay(500); | |
} | |
else //完成運算與運算後,將資料歸零 | |
{ | |
Serial.flush(); //確認傳送緩衝區資料傳送完畢 | |
data='/0'; | |
for(int m=0;m<7;m++){ | |
incomeByte[m]=0; } // 七個字節內的資料歸零 | |
} | |
z=0; // Z=6後,Z歸零 | |
} | |
} | |
} |
備註:
- L39~49 : 依序讀取感測數據所傳輸的七個字節,並儲存在incomeByte陣列中,其中起始字節為0xaa,十進制為170
- L50~53 : 完成七個字節的儲存後,將字節1~4加總,並比對是否和第五字節的校驗位相同,同時再次確認最後的字節是否為結束位的0xff
- L54~72 : 印出七個字節的數值(10進位),依照datasheet裡的公式,計算粉塵電壓與濃度,並列印出如下格式
- L73~79 : 清除七個字節的資料,繼續記錄下一筆的資料
範例結果:
討論:
- 影片中可以發現平常的粉塵數值大約10ug/m3左右,屬於優良的空氣品質,當香的煙霧靠近時,瞬間提升到汙染等級的空氣品質,當香的煙霧離開感測器時,粉塵數值又慢慢降回一班水準。
- 感測器內建的類比數位轉換器為10-bit,相對的解析度大約1.9ug/m3左右
- 比例係數A,有的人用500,有的人用700,我們則取datasheet內的平均直
- Vout公式 = (2x256 + 157) *5 / 1024 = 3.26V,中間 *5的部分,網路上很多只有乘上2.5,雖然不知道原因,但推測可能是上一版的Datasheet的建議直,在我們的程式中,還是按照建議值乘上五。
歡迎大家在底下留言或到我們的粉絲團留言喔!
====================================
fayalab 粉絲團
FB本篇留言版
沒有留言:
張貼留言