2018年10月23日 星期二

模組介紹 : faya灰塵感應模組


學習目標 : 認識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)


感測器內部的感測元件如下所式,粉塵會從感測器的圓洞進入,當粉塵經過檢出領域時,粉塵接收到光後所產生的散射,會被光感測器照接收,其能量以電壓的形式輸出。新一代的感測器內部還有一顆MCU和10bit的類比/數位轉換器,將接收的訊號轉成數位格式讓用戶讀取。


===================範例實作(1)===================
了解模組功能(原理)後,我們用以下範例來展示模組的功能:

目標:
(1)每0.5秒在Arduino Serial Monitor秀出目前的粉塵濃度

接線:
(1) 電源線連接
     如下圖所示,連接的說明請看這篇文章 簡易版


(2) 訊號線連接
      Arduino_D10  ===>  灰塵感應器_TXD


範例程式:
本次的範例程式,我們直接拿網路上署名Weesky維天監製的作者所提供的範例,稍作修改後並詳細解釋

// 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本篇留言版

沒有留言:

張貼留言