2018年2月1日 星期四

模組介紹 : faya人體感應模組


學習目標 : 認識faya人體感應模組的功能及使用方式
學習時間 : 40min
示範模組 : (1) faya brickNano
                   (2) faya人體感應模組
                   (3) faya 蜂鳴器模組
工具 : (1) 樂高積木底板 (相容)

====================功能介紹====================

faya人體感應模組使用了一人體紅外線感應器,利用人體發出的紅外線,偵測附近是否有人體移動,英文簡稱為 Motion Sensor。由於感應器只會偵測人體發出的紅外線,環境的光線並不會影響到偵測結果,因此夜間也適合使用。

faya人體感應模組的外觀如下所示,感測器的上方罩著一個半球型的菲涅耳透鏡,讓不同距離的人體紅外線都能聚焦在下方感測器的上。模組擁有兩個可變電阻,可用來調整輸出訊號的範圍,輸出訊號Vout可直接連接Arduino的類比腳位進行判斷。

  • 2K可變電阻可用來大範圍調整輸出電壓準位
  • 1M可變電阻可用來小範圍調整輸出電壓準位


====================原理知識====================
以下解釋提供給有需要知道背後原理的人:

半球形菲涅耳透鏡的下方,就是人體紅外線感測器,其外觀如下圖所示,感測器的上方有一片多層鍍膜 (optical filter),這層鍍膜阻絕了大部分波長的紅外線,只允許體溫36.5度左右所產生的紅外線波長通過,因此特別適合偵測人體的移動。


通過鍍膜的人體紅外線,照射到下方的SENSOR CRYSTALS產生電荷,電荷的變化會造成電壓的改變,進而偵測是否有人體移動。

 
上圖中可看出SENSOR CRYSTAL在電路中以成雙且極性相反的方式呈現,當未有人體靠近時,感測器未感應到紅外線,即使產生微弱的電荷,也會因為極相反而抵消,輸出不會有變動。

當有人體靠近時,由於兩個SENSOR CRYSTAL呈反向,因此會有一組SENSOR CRYSTAL先累積電荷,造成兩組電壓不平衡而改變輸出電壓,但是當人體靠近一段時間後,兩組SENSOR CRYSTAL累積的電荷會飽和,兩組電壓無差別,輸出電壓回復到初始狀態。


模組的電路圖如下所示,我們增加了一個放大電路,讓輸出電壓經放大後,在模組Vout埠輸出,其中2K的VR1用來調整輸入電壓的偏移(Offset),1M的VR2用來調整方大倍率(Gain)。由前一段的內容可以得知,PIR的應用,其輸出電壓的[高低]是沒有意義的,重要的是輸出電壓的[變化]。調整Offset和Gain時有兩個方向可以注意一下,屆時可以針對應用需求,透過Offset和Gain將輸出電壓調整至適當範圍。

(1) 調整Offset會大幅的改變輸出電壓,調整Gain會小幅的改變輸出電壓
(2) 當偵測到物體時,原本較高的輸出電壓的電壓改變量會較大,原本較低的輸出電壓的電壓改變量相對的也會變小。


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

目標:
(1) 當偵測到人體靠近時,模組上LED亮起
(2) 當偵測到人體靠近時,蜂鳴器播放音樂
(3) 可使用Serial Plotter輸出,用於觀察感測數值曲線變化(只支援1.6.6以上的IDE)

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


(2) 訊號線連接
      Arduino_A0  ===>  人體感應模組_Vout
      Arduino_D8  ===>  蜂鳴器模組_BZ


範例程式:
// 2018/01/24
// Faya-Nugget 範例程式 (MotionSensor_1.ino)
// 單元: 模組介紹-faya人體感應模組
// 網址: https://fayalab.blogspot.com/2018/01/PIR.html
// 目標 :(1) 當偵測到人體靠近時,模組上LED亮起
// (2) 當偵測到人體靠近時,蜂鳴器播放音樂
// (3) 可使用Serial Plotter輸出,用於觀察感測數值曲線變化(只支援1.6.6以上的IDE)
//
// 接線: Arduino ==> faya模組
// A0 ==> Vout (人體感應模組)
// D8 ==> BZ (蜂鳴器模組)
#include <Timer.h>
Timer t1; //建立Timer物件
int PIR_pin=A0; // 人體感應模組Vout連到Arduino A0
int LED_pin=13; // 使用Arduino上的 pin13 LED燈
int Buzzer_Pin_BZ = 8;// 蜂鳴器模組BZ連到Arduino D8
int motion_value=12; // 人體動作感應的判斷數值, 判斷範圍約:10~40
int sensor_value=0; // 感測器回傳的感測數值
int sensor_temp=0; // 感測數值的暫存器
int WelcomeSong[14] = {988,784, 587, 784, 880, 1175, 0, 587, 880, 988, 880, 587, 784, 0};
//全家歡迎光臨音階 Si ,La , Re , So, La , Re' , , Re , La , Si , La , Re , So, ,
int WelcomeBeat[14] = {4,4,4,4,4,2,4,4,4,4,4,4,2,4};
//全家歡迎光臨節拍 (X分音符)
void setup() {
Serial.begin(9600); //宣告UART的Board rate為9600
pinMode(LED_pin,OUTPUT); //宣告pin13(LED)為輸出腳
pinMode(Buzzer_Pin_BZ, OUTPUT); //宣告pin8(蜂鳴器)為輸出腳
//使用Timer.h的應用,功能為:每經過800毫秒,呼叫 LED_control Timer中斷副程式一次
t1.every(500, LED_Buzzer_control);
}
void loop() {
sensor_value=analogRead(PIR_pin); //從A0讀取人體感應模組的感測值
Serial.println(sensor_value); //將數值回傳到Serial Monitor (或者Serial Plotter)顯示
t1.update(); //按照預先設定的時間呼叫 LED_control 副程式
//校正時請先註解掉
}
void LED_Buzzer_control()
{
//當人體感應模組的感測值與500毫秒之前的感測值做個比較,
//如果相差超過判斷數值(motion_value),則使 pin13 的輸出為HIGH
//接著播放歡迎光臨的歌,並延遲2秒
if(sensor_temp - sensor_value >= motion_value)
{
digitalWrite(LED_pin,HIGH); //點亮LED
for(int i=0; i<=13; i++) //讀譜播歌
{
int toneDuration = 1000/ WelcomeBeat[i]; //算出每個音的撥放時間
tone(Buzzer_Pin_BZ, WelcomeSong[i], toneDuration ); //使用tone函式
delay(toneDuration * 1.1); // 保留相鄰音階之間的時間間隔
noTone(Buzzer_Pin_BZ);
}
delay(2000);
}
else //否則使 pin13 的輸出為LOW
digitalWrite(LED_pin,LOW);
//將這次人體感應模組的感測值儲存到暫存器中,
//等待下次的判斷
sensor_temp=sensor_value;
}


備註:
- 本範例用到Timer函式庫,可以避免耗掉CPU的資源,用法在註解中都會說明,有興趣的人可以參照這裡 學習更多Timer的用法並且下載Timer函式庫。也可從從這裡直接下載,下載後請自行解壓縮,將整個資料夾放在Arduino/liraries資料夾,重新開啟ArduinoIDE後生效。
- L19~L21, L48 : 如同原理知識提到的,當有人體經過的時候,會輸出電壓會產生變化,變化量會根據放大器的offset和gain而改變。因此我們程式裡面設定了3個變數,判斷電壓輸出的變化量,利用此變化量來判斷是否有人體經過。
- L33 : 設定Timer物件t1每0.5秒執行一次中斷副程式 (LED_Buzzer_control)
- L36~L41 : 我們利用analogRead 不斷的讀取人體感測器所讀到的值,然後每隔0.5秒 (500ms)呼叫執行一次中斷副程式 (LED_Buzzer_control)。
- L43~L59 :Timer t1的中斷副程式,每500ms會進入此程式檢查電壓變化量是否變大,有的話代表有人體經過,再進行點燈和撥放音樂的動作。播放音樂利用了tone函式庫,tone的用法在[模組介紹:faya蜂鳴器模組]已經詳細介紹過了,可以由此章節參考。
            
敏感度調整:
如前面原理知識中所提到的,起始的電壓愈高,當感測到人體經過時,電壓的改變量愈大,電壓改變的大小會牽涉到靈敏度,因此起始電壓的大小可以根據每個人的應用來調整,調整流程可以參考以下範例。

(1) 首先把第39行程式註解起來,不要執行Timer中斷副程式,讓監測更為流暢


(2) 上傳程式,成功後開啟Serial Plotter (請使用 1.6.6以上的IDE),此時會看到Arduino偵測到的電壓值A0會以曲線的方式呈現在Serial Plotter畫面,由圖中可看出筆者的analog起始值大約230左右,用手在上方揮一下,analog值大約下降到195左右,震幅改變達到35。


(3) 我們想把起始值調到650左右,達到更大的振幅,首先將兩個可變電阻順時針轉到底,並把模組的正面朝向沒有人體的方向,此時analog的數值約為750附近。


(4) 將標示2K的可變電阻逆時針旋轉,並把模組的正面朝向沒有人體的方向,直到analogh的數值穩定至650(±30)範圍內。


(5) 調整標示為10K的可變電阻逆時針旋轉,並把模組的正面朝向沒有人體的方向,直到analog的數值穩定至600(±30)範圍內。


(6) 用手在上方揮一下,analog值大約下降到520 左右,震幅改變達到80以上,遠大於程式中的移動差值(motion_value=12),因此會非常靈敏的判斷出是否有人體靠近。

(7) 取消第39行程式的註解,再次上傳程式完成調整動作。

範例結果:


討論:
(1) 由影片中我們可以看到前兩次當手揮過感測器上方後,類比變化值會下降,Arduino偵測到足夠的變化量後,就會開始撥放音樂。
(2) 第三次手揮到感測器上方時,手沒有移開,此時類比值會慢慢的上升回復到起始電壓,此時程式判定物體沒有移動,因此不會撥放音樂。
(3) 欲針對應用來修改感測的靈敏度,大家可以修改(A) 程式第12行的移動差值 (B) 程式第33行的中斷程式更新頻率 (C) 模組上的可變電阻。

歡迎大家到我們的FB留言板討論!
====================================
fayalab 粉絲團
FB本篇留言版


沒有留言:

張貼留言