Arduino 超聲波與紅外線感測器整合:打造全向障礙偵測系統
為光譜裡誰做:阿哲(想做避障小車)
Parent Gene:超聲波感測(14)、紅外線感測(09)
概念句:用超聲波加紅外線達成全向障礙偵測
想像一下:你在桌子上的小型避障小車,忽然遇到一隻手、一塊淺色保麗龍、和遠處的牆——三種不同的障礙,它都能正確停下來嗎?
單一感測器做不到。但把超聲波感測器(HC-SR04)和紅外線感測器加在一起,就可以。
1. 為什麼要整合?(互補特性分析)
超音波感測器(HC-SR04)
- 原理:發射超聲波,計算回傳時間 \text{Distance} = \frac{\text{Sonic Speed} \times \text{Time}}{2}。
- 優點:測距範圍廣(約 2cm ~ 400cm),對物體顏色不敏感。
-
缺點:
- 盲區:太近的物體測不准。
- 聲波散射:面對傾斜表面或吸音材料(海綿、布料)時,聲波被散射而回傳失敗,導致「看不見」障礙物。
紅外線感測器
- 原理:發射紅外光,偵測反射回來的光強度。
- 優點:反應速度快,適合近距離偵測(邊緣偵測、極近障礙)。
-
缺點:
- 深色物體吸收紅外光:黑色或深色表面會讓偵測距離大幅縮短甚至完全偵測不到。
- 環境光干擾:強烈陽光(含紅外線成分)可能造成誤判。
整合策略:雙重驗證
| 情境 | 超音波結果 | 紅外線結果 | 系統判定 |
|---|---|---|---|
| 遠處有牆 | \text{Distance} < 20\text{cm} | 無觸發 | 障礙物(遠) |
| 面對淺色保麗龍(多孔) | 無回傳(散射) | 觸發(吸光少) | 僅超聲波(超聲波盲,IR 補上) |
| 面前有白色牆壁 | \text{Distance} < 5\text{cm} | 觸發 | 障礙物(極近) |
| 空曠環境 | \text{Distance} > 20\text{cm} | 無觸發 | 安全 |
阿哲可能遇到的問題:為什麼淺色保麗龍讓超聲波「失效」了,但紅外線卻測到了?因為保麗龍表面軟、多孔,聲波散射回不上來,但紅外光仍能反射回讀——兩種感測器的物理特性不同,剛好互補。
2. 硬體接線
元件清單
- Arduino Uno 或 Nano × 1(約 NT200-300)
- HC-SR04 超聲波模組 × 1(約 NT50-80)
- 紅外線障礙偵測模組 × 1(約 NT30-50)
- 麵包板、杜邦線
接線表
| 元件 | 引腳 | Arduino 引腳 | 說明 |
|---|---|---|---|
| HC-SR04 | VCC | 5V | 電源 |
| Trig | D9 | 觸發脈衝 | |
| Echo | D10 | 接收回傳 | |
| GND | GND | 接地 | |
| IR Sensor | VCC | 5V | 電源 |
| OUT | D2 | 偵測訊號(Low = 偵測到) | |
| GND | GND | 接地 |
3. 程式碼實現
// 定義引腳
const int TRIG_PIN = 9;
const int ECHO_PIN = 10;
const int IR_PIN = 2;
const long MAX_DISTANCE = 300; // sentinel 值:代表「測不到/超範圍」,不是真實可測距離(pulseIn timeout 限制實測上限約 51cm)
const int DEBOUNCE_COUNT = 3; // 連續偵測次數
int stableCount = 0; // 紅外線穩定計數
void setup() {
Serial.begin(9600);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(IR_PIN, INPUT);
digitalWrite(TRIG_PIN, LOW);
Serial.println("System Initialized: 超聲波 + 紅外線融合");
Serial.println(">> 校準:打開 Serial Monitor,確認數值正常 <<");
}
long getUltrasonicDistance() {
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
// pulseIn timeout = 3000μs → 實測上限約 51cm(來回 102cm)。超過就回傳 MAX_DISTANCE(sentinel)
long duration = pulseIn(ECHO_PIN, HIGH, 3000);
if (duration == 0) return MAX_DISTANCE; // 無回傳視為超範圍 / 未知
return duration * 0.034 / 2;
}
void loop() {
long distance = getUltrasonicDistance();
int irDetected = digitalRead(IR_PIN);
Serial.print("距離: ");
Serial.print(distance);
Serial.print(" cm | IR: ");
Serial.println(irDetected == LOW ? "偵測到!" : "無");
// 整合邏輯:加括號避免優先順序錯誤
bool ultrasonicTrigger = (distance > 0 && distance < 20);
bool irTrigger = (irDetected == LOW);
// 防雜訊:紅外線連續 3 次偵測到才算數
if (irTrigger) {
stableCount++;
} else {
stableCount = 0;
}
if (ultrasonicTrigger || (stableCount >= DEBOUNCE_COUNT)) {
Serial.println(">>> 障礙物!停車! <<<");
// motorStop(); // 在這裡加入馬達停止指令
} else {
Serial.println("路徑暢通,前進中...");
// motorForward(); // 在這裡加入馬達前進指令
}
delay(200);
}
技術細節:為什麼要加 timeout?
pulseIn()預設可以等很久。如果超聲波沒收到回傳(例如面對吸音海綿),它會卡住直到收到為止——這段時間小車可能已經撞上了。
加入 timeout 參數(微秒)後,3ms(= 3000 微秒)內沒收到回傳就回傳 0,我們立刻知道「這次沒測到」,而不會卡死。聲音在空氣中每秒約走 340 公尺,也就是每秒 34,000 公分,所以每微秒約 0.034 公分。duration * 0.034 / 2 這個公式就是把微秒轉換成來回的距離(公分)。
MAX_DISTANCE 只是 sentinel 值,表示「測不到」,不代表真的 300cm。當超聲波完全收不到回傳時,pulseIn 回傳 0,我們回傳 MAX_DISTANCE,邏輯會走到 distance > 0 && distance < 20 這個超聲波觸發條件,結果是 false——這時候紅外線的 stableCount 就會在它感測到障礙時觸發。兩個感測器互相當作 backup。
4. 動手驗證(阿哲測試清單)
- 超聲波測試:拿一本書慢慢靠近,Serial Monitor 顯示的數值是否符合實際距離?
- 紅外線測試:用手靠近/遠離模組,觀察訊號燈和 Serial Monitor 輸出。
- 軟質材料測試:拿一塊白色或淺色保麗龍測試——超聲波可能失效(散射),但紅外線仍能偵測到(淺色表面反射紅外光良好),這正是兩種感測器互補的好例子。黑色海綿則是兩者的共同盲區——聲波散射 + 紅外光吸收,同時失效。
- 整合測試:同時觸發兩個感測器,確認「雙重驗證」邏輯正確。
5. 讓阿哲問的問答
Q:為什麼保麗龍讓超聲波測不准?
A:超聲波靠「聲波反射」回傳資訊。保麗龍、海綿等軟質/多孔材料會把聲波散射吃掉,幾乎沒有反射。紅外線靠「光反射」,如果表面是淺色,同樣能反射回讀——兩者互補。
Q:可以把這個邏輯用在循線小車上嗎?
A:可以。把紅外線模組朝下安裝,當車輪接近桌面邊緣時,紅外線訊號會從「無反射」變成「有反射」(桌面 vs. 懸空),就能及時停住。
Q:pulseIn 的 timeout 要設多少?
A:這題是物理+設定的混合問題。pulseIn() 的 timeout 參數單位是微秒(μs)。聲音在空氣中每秒約走 340 公尺(每秒 34,000 公分),所以每微秒約走 0.034 公分。來回 100cm(大約手臂伸直的距離)約需 2.9ms(= 2900 微秒)。pulseIn() 設 3000(微秒)表示:等 3ms 還沒有回傳就放棄。實務上 3ms timeout 讓 HC-SR04 最遠約測到 51cm(單程)——超過這個距離的障礙,會被視為「無障礙」。這是超聲波感測器的物理上限,不是程式的錯。
結論
超聲波的「遠距掃描」與紅外線的「近距補完」,剛好從兩個方向覆蓋了單一感測器的盲區。
這個整合做起來不貴(全部材料約 NT300 以內),邏輯也清晰——而且讓你真正理解「感測器融合」在實務上長什麼樣子。
動手門檻:國中生程度可以接線,但程式邏輯建議有高一以上基礎。或請旭豐帶你走一遍。
Top comments (0)