一、 實驗說明:讓 ESP32 具備「空間距離感測」能力!
在物聯網(IoT)的許多自動化專案中,我們常需要讓裝置能夠判斷前方是否有障礙物、測量距離,甚至是偵測人體靠近(例如:自動感應垃圾桶、倒車雷達警示系統、自動避障小車)。
本實驗我們將介紹創客圈最熱門的 HC-SR04 超音波測距模組。我們將學習超音波發射與反射接收的基本物理原理,透過 ESP32 計算聲波往返的時間,精準轉換出目標物體的距離(公分)!
二、 實驗材料準備清單
本篇實作超音波測距專案所需的硬體元件如下:
ESP32 開發板
麵包板 (Breadboard)
HC-SR04 超音波測距模組
杜邦跳線
USB 傳輸線
🛒 一次備齊創客工具!
歡迎直接購買米羅科技的 ESP32 物聯網應用學習套件,免去東奔西跑湊零件的煩惱。內含 HC-SR04 超音波感測器、各類感測器及基礎電子元件,是學校課堂教學與個人專案開發的最佳首選!
三、 核心知識:HC-SR04 超音波測距原理與公式
1. 超音波運作原理
HC-SR04 模組上有兩個圓形的超音波元件:
Trig(觸發端 – Transmitter):發出高頻超音波(40kHz)。
Echo(接收端 – Receiver):接收被物體反射回來的超音波。
當 Trig 收到高電位訊號時,會發射聲波;聲波碰到障礙物反射回來被 Echo 接收後,Echo 腳位會保持高電位一段時間,這段高電位的時間長短就代表聲波往返的時間(微秒 microseconds)。
▼ 其規格如下
- HC-SRO4 可以感測的距離為 2cm 到 400cm,感應角度為 15 度。
- 給trig pin一個10 us TTL pluse, 模組會發射8個40k Hz的聲波出去,然後量測訊號是否回來。
- 如果有收到TTL的高電位訊號,那Echo會送出超音波來回的時間,此 HIGH 位準脈衝上緣可以看成超音波開始發射時間; 而下緣則是接收到反射波的時間, 所以整個高位準脈衝的寬度就是超音波往返的總時間。
2.Echo pulse的時間長度呢?
聲波的傳遞速率:音速又會依空氣之狀態(如濕度、溫度、密度)不同而有不同數值。所以使用超音波量測距離必須知道音波的傳遞速度, 這主要取決於大氣的密度, 而溫度又是影響空氣密度的主因. 音速與溫度的關係如下 :
V=331m/s +0.6t
(V:空氣中的音速;t:空氣中的攝氏溫度)
在常溫 20 度時, 音速是 331.5+0.6*20=343.5 m/s
超音波測距的原理是利用一個超音波發射器與一個接收器組成的模組來量測音波從發射到收到反射波的時間, 乘以音速即可得到音波往返的距離, 除以 2 即得與反射物體間的距離. 在常溫 20 度下, 音波前進 1 公分約需 58 微秒, 計算如下 :
1 公分=0.01公尺
0.01 公尺=(343.5 公尺/秒*t)/2
此處除以 2 是因為音波花了 t 秒往返走了兩倍距離, 須除以 2 才是單程距離.
t=(0.01*2)/ 343.5 =58us(微秒)
四、 電路接線與實作步驟
VCC ➜ 連接至 ESP32 的
5VGND ➜ 連接至 ESP32 的
GND。Trig ➜ 連接至 ESP32 的
GPIO 17。Echo ➜ 連接至 ESP32 的
GPIO 16。
五、 實作實驗程式碼:讀取與計算距離
請將以下程式碼複製到 Arduino IDE 中並上傳:
1. 範例程式碼
int trigPin=17; //發出聲波腳位(ESP32 GPIO17)
int echoPin=16; //接收聲波腳位(ESP32 GPIO16)
void setup() {
pinMode(trigPin, OUTPUT);
Serial.begin(9600);
}
void loop() {
unsigned long d=ping()/58; //計算距離
Serial.print(d);
Serial.println("cm");
delay(1000);
}
/*副程式
*Send 10us pulse to HC-SR04 trigger pin
*/
unsigned long ping() {
digitalWrite(trigPin, HIGH); //啟動超音波
delayMicroseconds(10); //sustain at least 10us HIGH pulse
digitalWrite(trigPin, LOW); //關閉超音波
return pulseIn(echoPin, HIGH); //計算傳回時間
}
2. 燒錄與操作測試
點擊 Arduino IDE 的 [上傳 (Upload)] 按鈕。
開啟 [序列埠監視器 (Serial Monitor)],將鮑率設定為
9600。拿一塊板子或用手在 HC-SR04 前方移動,觀察序列埠監視器上顯示的公分數值是否隨著距離遠近而即時改變!
▼輸出結果如下:
程式說明:
HC-SR04 的 Trig 腳送出 10 微秒的 HIGH 準位脈衝, 以觸發發射器送出超音波, 然後用 pulseIn() 函數測量 Echo 腳送出的 HIGH 脈衝寬度傳回. 此值為超音波往返的時間 (微秒), 將其除以 58 即得與障礙物之間的距離 (公分).
pulseIn ( ) 函式使用方式:
在Arduino裡有現成的指令“pulseIn ( )” 為讀取一個針腳的脈衝時間(HIGH或LOW)。
此函數有 2 或 3 個參數 :
pulseIn(pin, value)
pulseIn(pin, value, timeout)
- 第一參數 pin 是 Arduino 接 HC-SR04 的 Echo 腳之 DIO 數位腳位編號,
- 第二參數 value 是要偵測的位準 (LOW/HIGH), 對於 HC-SR04 而言要用 HIGH,
- 第三參數 timeout 是等候脈衝出現的延遲時間 (單位是微秒), 預設是 1 秒 (即1000000). 如果在 timeout 時間內未偵測到脈衝, 則回傳
進階範例(測距槍)
在這個範例中,米羅將帶各位實作一個好玩又實用的測距槍,測距槍搭載了超聲波模組與LCD1602 顯示模組,可對 1~400cm 範圍內物體進行測距,測出的距離將顯示在 LED 面板上。
接線說明:
程式:
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display
int trigPin=17; //發出聲波腳位(ESP32 GPIO17)
int echoPin=16; //接收聲波腳位(ESP32 GPIO16)
/*副程式
*Send 10us pulse to HC-SR04 trigger pin
*/
unsigned long ping() {
digitalWrite(trigPin, HIGH); //啟動超音波
delayMicroseconds(10); //sustain at least 10us HIGH pulse
digitalWrite(trigPin, LOW); //關閉超音波
return pulseIn(echoPin, HIGH); //計算傳回時間
}
void setup()
{
pinMode(trigPin, OUTPUT);
lcd.init(); //初始化LCD1602
lcd.backlight(); //開啟背光
}
void loop()
{
unsigned long d=ping()/58; //計算距離
lcd.clear(); //清除所有內容
lcd.setCursor(0,0); //游標從第0行,第0個字開始印出文字
lcd.print("Distance : "); //印出文字
lcd.setCursor(0,1); //游標從第1行,第0個字開始印出文字
lcd.print(d); //顯示距離
lcd.print("CM");
delay(1000);
}
六、 初學者常見卡關問題與排錯指南(Troubleshooting)
Q:為什麼有時候量超過 400 公分就不準了?
硬體極限:HC-SR04 的有效量測範圍約為
2cm ~ 400cm,感測角度約 15 度。若超過這個範圍或物體表面太過柔軟吸音(例如毛絨布料),聲波無法順利反射,就會導致數據失真。
七、 結語與下一篇教學
恭喜你!成功學會了使用 ESP32 搭配 HC-SR04 測量距離。下一篇教學,我們將帶大家進入更多精彩的 ESP32 DHT11溫濕度感測!







