在前一篇文章 Raspberry Pi 3 Model B 與 HC-SR04 超音波感測器之應用 中我們利用 Python 的 hcsr04sensor 套件來取得 HC-SR04 超音波感測器所偵測出的距離。在這篇文章中,我們將解釋 HC-SR04 的運作原理,並利用 Python 的 RPi.GPIO 模組與 HC-SR04 進行互動。

超音波與回聲

在國中的自然與科學中,我們學到回聲 (回音) 的概念,並且利用聽到回聲的時間差來判斷障礙物 (如山壁) 與我們之間的距離。而這正是 HC-SR04 所利用的原理,只不過 HC-SR04 利用的是我們聽不到的聲波,稱為超音波。

雖然每個人對聲音的感受能力不太一樣,不過一般人只能夠聽到頻率在 20Hz ~ 20KHz 之間的聲波,所以將頻率高於 20KHz 的聲波統稱為超音波。HC-SR04 使用的頻率為 40KHz,所以當 HC-SR04 在工作時,儘管其依靠的是回聲的偵測,我們卻是聽不到任何聲音的。

發聲體與障礙物之間距離的公式如下:
\begin{align}
聲源與障礙物的距離 (公尺) & = \frac{發出到接收聲音的時間 (秒) \times 聲音的速度 (\frac{公尺}{秒})}{2}\\
& = \frac{發出到接收聲音的時間 (秒) \times 343 (\frac{公尺}{秒})}{2}\\
& = 發出到接收聲音的時間 (秒) \times 171.5 (\frac{公尺}{秒})\\
聲源與障礙物的距離 (公分) & = 發出到接收聲音的時間 (秒) \times 171.5 (\frac{公尺}{秒})\times 100 (\frac{公分}{公尺})\\
& = 發出到接收聲音的時間 (秒) \times 17150 (\frac{公分}{秒})\\
\end{align}
請記得 17150 這個數字,之後在撰寫程式代碼時會需要用到。

在我們講解 HC-SR04 的訊號方式前,我們複習一下有關聲波的一些基本特性。

  • 聲波在反射時,頻率是不會改變的。所以我們聽不到反射前的超音波,也不可能聽到反射後的超音波。反射前後的聲波頻率都超過人類聽覺可以感受的範圍。
  • 聲音在空氣中傳播的速度比水中慢,而在水中的傳播速度又比固體 (如金屬) 中的傳播速度慢。
  • 在 $20^oC$ 的空氣中,聲波的速度約為 $343 \frac{公尺}{秒}$。當溫度越高時,聲波的速度也會越高。反之,當溫度越低時,聲波的速度也會越低。我們在前面的公式中並沒有將溫度的影響考慮進去,所以將會產生一定的誤差。
  • 聲波傳播的速度與聲波本身頻率高低無關,因此超音波的速度與我們一般可聽到的聲波速度一樣。
  • 在我們的範例中,HC-SR04 是處於靜止的狀態,所以可以使用此一計算公式。但是很多遙控小車也同樣配置 HC-SR04 以做為防碰撞之用,他們的計算公式又是如何?照理說,如果聲源處於移動的狀態,計算公式就必須考慮聲源移動的速度與方向。然而因為遙控小車並不容易取得這些資訊,所以實際計算時,往往還是使用同一個公式來加以計算,也就是把遙控小車當成靜止不動。
  • 因為遙控小車的移動速度通常比聲波的速度慢上許多,所以這樣的假設是可以接受的。但是如果你的遙控小車擁有超級移動力,那肯定不能使用此一公式了。想像一下,如果遙控小車的移動速度比聲音還快,它還能夠接受到任何的回聲嗎?

HC-SR04 訊號時序圖

下圖是 HC-SR04 的訊號時序圖。首先我們必須對 Trigger 接腳發出一個持續時間大於 10$\mu$s 的高電位訊號,而 HC-SR04 收到此一訊號後就會連續發出 8 個頻率為 40KHz 的超音波。之後 HC-SR04 會在 Echo 接腳輸出一個高電位訊號,而訊號維持的時間就是發出聲音到接收回聲兩者之間的時間差距。 也就是說,當我們透過 Trigger 接腳通知 HC-SR04 開始偵測距離後,只要量測 Echo 接腳高電位的時間長度,就可以知道 HC-SR04 經過多久時間才收到回聲。

HC-SR04 時序圖

HC-SR04 時序圖

Python 虛擬環境配置

因為這個範例只需要 RPi.GPIO 套件,所以準備工作與 在 Raspberry Pi 3 Model B 建立 Python 3.6 環境 一致。如果你還沒有完成相關的準備,請務必先行完成再繼續進行後面的工作。

電路圖

Raspberry Pi 3 Model 與 HC-SR04

Raspberry Pi 3 Model 與 HC-SR04

此電路與前一篇文章 Raspberry Pi 3 Model B 與 HC-SR04 超音波感測器之應用 中的電路完全一致。

程式代碼

利用文字編輯器 (如 nano) 新增 Python 程式 hc_sr04_raw.py

內容如下

程式說明如下:

  1. 第 1 行引入 RPi.GPIO 模組,這次我們直接利用 GPIO 模組與腳位進行互動,而不再使用之前的 hcsr04sensor 套件。
  2. 第 4 行定義 HC-SR04 Trigger 接腳所連結之 GPIO 腳位 BCM 編號。
  3. 第 5 行定義 HC-SR04 Echo 接腳所連結之 GPIO 腳位 BCM 編號。
  4. 第 7 行設定使用 BCM 的腳位編號方式。
  5. 第 8 行設定 Trigger 所使用的腳位為輸出。
  6. 第 9 行設定 Echo 所使用的腳位為輸入。
  7. 第 11~12 行指令先將 Trigger 維持一秒鐘的低電位狀態,以便 HC-SR04 能夠正確解讀出之後 Raspberry Pi 送出的控制訊號。
  8. 第 17~19 行指令送出 10$\mu$s (念法為 10 微秒,微秒是 $10^{-6}$ 秒) 的高電位訊號,控制 HC-SR04 開始進行距離的偵測。
  9. 第 20~24 行計算 Echo 腳位高電位的持續時間。因為一開始 Echo 腳位處於低電位,所以程式持續偵測該腳位是否變換至高電位,並記錄發生變換的時間 (第 20~21 行)。之後程式則持續偵測該腳位是否變換至低電位,並記錄發生變換的時間 (第 22~23 行)。兩者之間的差距就是 Echo 處於高電位的時間,也就是 HC-SR04 收到回聲所需的時間。
  10. 第 25 行將收到回聲的時間乘以 17150 後,即為 HC-SR04 與障礙物之間的距離 (單位為公分)。
  11. 第 26 行將偵測結果輸出在畫面上。
  12. 第 27 行暫停 10 秒後再次重新偵測距離。
  13. 第 31 行確保程式結束執行時能夠將程式中所使用的腳位回復至預設狀態。

程式完成後,輸入下列指令執行程式

順利的話,畫面上就會出現距離的訊息。而當我們用手或東西檔在 HC-SR04 的前方時,偵測到的距離也會隨之改變,類似下列的畫面輸出:

我們接著利用 piscope 來觀察 Echo (BCM 編號 8,在下圖上方) 與 Trigger (BCM 編號 25,在下圖下方) 腳位的波形,可以發現在 Trigger 腳位出現短時間的高電位訊號後,Echo 腳位出現一段長時間的高電位訊號,時間維持約 10.84 微秒 (0.01084)。而此時間就是 HC-SR04 收到回聲的時間差,換算成距離則為 $10.84 \times 10^{-3} \times 17150 \approx 185.9 (公分)$,BINGO!

piscope 觀看 HC-SR04 輸出波形

piscope 觀看 HC-SR04 輸出波形

在這個範例中,我們了解到 HC-SR04 的偵測原理,並利用 GPIO 模組與其互動。與之前使用 hcsr04sensor 套件時相比,程式變得較為複雜,而且還不具備依據溫度調整偵測結果的能力,更沒有辦法直接輸出英制單位。在實際的開發過程中,找到合適且好用的套件,往往可以幫助我們省下很多心力,應該盡量多加利用。

如果對文章的內容有任何疑問或建議,歡迎與我聯絡。

Facebook 留言
Print Friendly, PDF & Email
Summary
Raspberry Pi 3 Model B 與 HC-SR04 超音波感測器之原理釋疑
Article Name
Raspberry Pi 3 Model B 與 HC-SR04 超音波感測器之原理釋疑
Description
在這篇文章中,我們將解釋 HC-SR04 的運作原理,並利用 Python 的 RPi.GPIO 模組與 HC-SR04 進行互動。
Author
Publisher Name
Everlearn Studio
Publisher Logo