學習目標 : 認識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
範例程式:
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/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本篇留言版
沒有留言:
張貼留言