
IR object detection with Arduino --- Arduino 紅外線物體偵測 (1)
這裡的 紅外線物體偵測 不是 熱感應 的那種, 而是使用 反射光原理 的那種,
為了要讓 機器人能利用 紅外線 做物體偵測, 先要對所使用的的元件稍有些了解,
這樣比較好掌握使用的方式和技巧.
首先, 先要了解有哪些紅外線元件可用,
材料行裡最容易找到的, 不外乎就是紅外線發光二極體和紅外線接收器, 兩者單價都不貴,
紅外線發光二極體 長得和一般的發光二極體沒甚麼明顯差別, 而且可能一模一樣,
有的塑料外殼是完全透明的, 有的則像下圖一樣, 是淡藍色的.
當然也有別的形狀的 (例如方型的), 隨你喜歡, 大小也有一些差別.
最好找那種店家有清楚標示紅外光波長的, 一般來說有 850nm 和 940nm 兩種.
下圖這個, 我不知道發射波長是多少, 最後我選用全透明外殼的, 波長是 940nm.
紅外線接收器, 接收器也有很多種, 常見的也有長得像一頒發光二極體的,
我則比較喜歡撿現成的, 紅外線接收器模組, 這是有一定考量的. 後面一點再做說明.
底下這種是常見的其中一種, VISHAY.
也有各種規格, 尺寸大小, 工作頻率等都有不同,
這顆很大一顆. 工作在 38KHz.
使用起來非常簡單, 5V, GND 和 Output.
當收到 38KHz 調變的紅外線時, Output 會輸出 low; 反之則輸出 high. 就這麼簡單.
這種接收模組通常用來做紅外線資料傳輸, 也有被用來做遙控器的.
這裡有個很好的例子.
大家這幾個月應該在玩具店, 大賣場, 或者模型店,
應該或多或少都有注意到下圖這個東西 --- 遙控直升機,
這小小的直升機如洪水般氾濫在各賣場商家, 已經流行好一陣子了,
雖然還沒到人手一架, 但應該吸引了不少人的目光.
現在拜各項科技的進步, 元件的商用化快速, 以前高貴且稀有的陀螺儀, 現在已經可以裝在這種單價在幾百元的玩具上了.
不過我們今天的重點不在陀螺儀, 而是紅外線.
這類的微型直升機大多是以紅外線遙控, 所以, 一定可以在他身上找到紅外線接收器.
就在直升機的底部, 很容易就找到它了, 只是他所用的是屬於更小型的的接收器, 但是原理完全相同.
我第一次裝在機器人身上的紅外接收器就是用這大顆的, 後來因為嫌他太大,
也不需要長距離接收, 所以後來換掉了.
車頭左右各裝一顆, 好像汽車的頭燈一樣.
有關機器人的應用, 稍後在介紹.
最後用在機器人身上的 紅外線接收器 是這種的.
這種接收器小很多, 應該可以在很多裝置上看到,
工作頻率有好幾種, 36~39KHz 都有, 我用的是 38KHz, 940nm 的.
用法也跟 VISHAY 的一樣, 只是腳位不同.
號稱可接收距離可達 35 m, 不知道是甚麼條件下量的.
要先確定元件本身都沒問題, 所以在麵包板上街上簡單電路,
一端發射, 另一端則接收, 用示波器確認相關信號都有正常出現.
發射端很簡單, 紅外線發光二極體 串聯一顆電阻, 一端接到 Arduino, 一端接地.
接收端更簡單, 5V 和 GND 接上便行了.
換另一種紅外線發光二極體 試試看.
準備做反射實驗.
用白紙做反射實驗, 測試最大可用距離.
這距離會跟 發射端的亮度有關, 發射端的亮度則以流過 紅外線發光二極體 的 電流 來決定.
電流的控制則是靠 限流電阻.
Arduino 的 digital pins 電流輸出最大到 40mA.
下圖黃色的波形是發射端的電壓變化, 是以 burst 的方式輸出,
藍色的波形則是接收器的輸出端電壓, 此時沒有收到夠強的 38KHz 的調變光.
下圖則是在接收器收到反射光了, 所以輸出了一個 low pulse.
而且接收端輸出顯然比發射端晚了一小段時間.
接收端輸出比發射端晚了約 172 us.
我猜這是接收端輸電路的反應時間 (response time).
不過我還沒去查證.
因為接收器實在太靈敏了, 必須把發射器用黑膠布裹一裹,
不然接收器很容易收到其他東西的反射光.
另外, 要注意的是, 不同材質, 顏色的物體, 對紅外光的反射率是不一樣的,
所以接收器能感受到的反射光強弱就不同, 也代表可測距離就會不一樣.
最後, 說明一下為什麼要用所謂的 紅外線接收模組 來做為接收器,
一般的紅外線接收元件不行嗎? 紅外線光電晶體不行嗎?
其實所謂的 紅外線接收模組 也有這些感光元件, 骨子裡是一樣的,
不一樣的是, 接收模組裡有放大電路, 可以放大鎖接收到的微弱信號(這裡指的是紅外光),
更有濾波電路, 可濾掉不要的雜訊 (這裡指的是其他紅外線光源所發出的光).
事實上在我們周遭有著各種紅外光源, 包含人體, 各種電器, 電燈, 乃至太陽光,
因此, 我們紅外線接收器所接收到的光線可以是來自任何一種光源所發出來的紅外光線,
只要波長在能感受到的範圍內, 通通都會被收到, 而我們的發射源只是其中之一.
如何過濾掉不要的雜訊, 只取我們要的光?
聰明的人類想出了一種做法, 就是將我們的發射源的所發出的光, 做某種頻率的調變,
讓他跟其他的 雜光 不一樣, 而接收端在收到光線後, 將光的強弱轉換成電壓高低變化,
然後使用率波電路, 將有經過特定頻率調變的信號過濾出來, 其他的則通通丟掉,
這樣就達到只看發射器所發射的光線的目的. 這就好像電視或收音機在做選台的道理一樣.
一般而言, 紅外線的調變頻率大多在 38KHz 附近, 所以買零件的時候要注意一下規格,
也不是說發射和接收的頻率不一樣就完全收不到, 只是性能會大打折扣而已(例如接收距離變短).
這種做法, 在很多的家電遙控器都有用到, 用示波器量量看就知到了.
當然當雜光訊號很強, 強過我們的發射信號時, 這一切就都沒用了.
下面是我用來 Arduino 產生 38KHz 的程式.
有兩個發射和接收端.
/******************************************************************
IR_Test1
IR burst generation
Leo Chen (http://tw.myblog.yahoo.com/galileo-sky)
2010/6/6
******************************************************************/
void setup() {
Serial.begin(9600);
// initialize the digital pin as an output:
pinMode(7, OUTPUT);
// prints title
Serial.println("IRTest v0.2");
}
void loop() {
EmitIR();
delay(100); //
}
void EmitIR() {
int i;
//Pin 7
for (i=0; i<20; i++) {
//digitalWrite(7, HIGH);
PORTD |= 0x80;
PORTB |= 0x20;
PORTB ^= 0x20;
//j +=1;
delayMicroseconds(13);
//digitalWrite(7, LOW);
PORTD ^= 0x80;
PORTB |= 0x20;
PORTB ^= 0x20;
//j +=1;
delayMicroseconds(13);
}
}