超音波感應器蠻常出現在電子機器人的產品上,通常是用來測量距離,超音波感應器各有一個發射及接收超音波的零件,活像兩顆大大的眼睛,在製作機器人時,就經常成為造型之一 … XD
認識超音波感應器
如上圖看到的,我手邊這顆超音波感應器為 HC-SR04,左邊被標示為 T 的那顆是發射器(Transmitter),會發出 40 kHz 的聲波,這個聲波超出人類可感知的 20 kHz 上限,因此才稱之為超音波,右邊那顆被標示為 R 的是接收器(Receiver),可接收超音波。
HC-SR04 腳位從左至右分別為 Vcc、Trig、Echo 與 GND,Vcc 與 GND 就是接 5V 電源及 GND 了,Trig 為輸入腳位,Echo 為輸出腳位,超音波的發射與接收,就是靠 Trig 與 Echo 這兩個腳位,如果你送出 10 微秒的 5V 高電位訊號給 Trig,就會觸發超音波的發射,接著 Echo 腳位就會處於 5V 高電位狀態,如果接收到反射的超音波訊號,那麼 Echo 腳位就會處於 0V 低電位狀態:
因此,在超音波發射之後,Echo 的高電位持續時間,就可以搭配音波速度每秒 343.2 公尺,也就是每公分要花費 29.1 微秒左右,計算出超音波感應器與障礙物之間的距離,記得音波往返是走了兩倍距離,因此 Echo 的高電位持續時間要除以 2,再用來除以 29.1 微秒,才是與障礙物之間的距離。
如果使用 Arduino 官方語言的話,可以如下撰寫程式,以取得超音波感應器與障礙物之間的距離:
digitalWrite(TRIGPIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIGPIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIGPIN, LOW);
double dist = pulseIn(ECHOPIN, HIGH) / 58.2; // 公分
pulseIn
函式可以計算指定腳位的高電位或低電位持續時間,單位是微秒。
使用 mBlock 超音波感應器方塊
嗯?delayMicroseconds
與 pulseIn
在 mBlock 中並沒有對應的方塊,因此,沒什麼好繼續介紹的了?
實際上,在 mBlock 2.1 中,機器人模塊中的 Makeblock 區塊裏有個「超音波感應器」方塊,這原是搭配 Makeblock 超音波感應器模組而使用,這個超音波感應器模組使用 RJ11 接頭,而 Makeblock 在 Arduino 板子上設置了八個 RJ11 連接埠,你可以在 Me-Baseboard 看到相關圖片說明。
在說明中,可以看到 Ports on Baseboard Orion to pins on Arduino UNO 這張圖,假設我想將超音波感應器連接在 3 號連接埠,它對應的腳位是 D12 與 D13,而在 The Upgrade of Me Series Electronic Modules 的說明中可以看到,Makeblock 的超音波感應器模組,似乎只是將 Vcc、Trig、Echo 與 GND,直接對應至 RJ11 的相關接點,因此,就來試試看用這個方塊吧!
搭配上面這個程式,試著使用以下的電路連接,Trig 連接 D12,Echo 連接 D13:
接著執行程式,你就可以看到貓咪跟你報告距離了 … XD
如果你試著使用 mBlock 超音波感應器方塊,然後轉為 Arduino mode 檢視 Arduino 原始碼,可以發現,它實際上是 MeUltrasonic 程式庫,這可以在 mBlock 安裝目錄的 ext/libraries/makeblock/src 中找到對應的原始碼,其中控制超音波感應器的程式碼,主要是在 measure
函式:
long MeUltrasonic::measure(unsigned long timeout)
{
long duration;
MePort::dWrite2(LOW);
delayMicroseconds(2);
MePort::dWrite2(HIGH);
delayMicroseconds(10);
MePort::dWrite2(LOW);
pinMode(s2, INPUT);
duration = pulseIn(s2, HIGH, timeout);
return duration;
}
MePort
的 dWrite2
中,基本上就是在對應腳位作 digitalWrite
的動作(依 makeblock 的埠決定哪個腳位):
void MePort::dWrite2(bool value)
{
pinMode(s2, OUTPUT);
digitalWrite(s2, value);
}
依這個寫法模式,似乎很像是 HC-SR04,不過,依上面的程式碼來看,它都只用到 s2
,也就是腳位 13
,為什麼呢?因為 Makeblock 最新的超音波感應器 V3.0,可以自行使用杜邦線接線的腳位只有三個:
三個腳位中,有兩個分別是接電源與 GND,一個是信號接腳,這意謂著,Trig 與 Echo 必須使用同一個腳位,這也就是為什麼,在 measure
的程式碼中,看到的都只有使用 s2
腳位。
可是 HC-SR04 是四個腳位,Trig 是其中獨立的一個腳位,怎麼能適用「超音波感應器」方塊呢?自行觸發 Trig 囉!只是直接使用「設置數位腳位」方塊的速度不夠快,因此,我想到的是,使用「播放腳位」方塊,這可以控制腳位電壓高低的頻率,建立起類似以下的效果:
digitalWrite(TRIGPIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIGPIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIGPIN, LOW);
簡單來說,最後我就只是利用了「超音波感應器」方塊底層的 pulseIn
來取得回波時間而已,這個方法下測出來的距離數值會跳動,不過大致上勉強可用啦!
(這個方法比較適用於 mBlock 2.1.4,在 mBlock 2.1.5 中,韌體上似乎做了些修改,雖然還是可以用相同方法,不過,跳動的範圍會變大許多。)
超音波搭配七段顯示器
那麼,就也來回顧一下〈mBlock & Arduino(7)七段顯示器之 HELLO!〉,試著將超音波感應器量得的距離,使用七段顯示器來回報吧!
因為只有一顆七段顯示器,超過 8 公分就一律顯示為 0 了 … XD
清單 numbers 使用字串編碼 0 到 8 的數字: