Arduino筆記(十九):超音波測距模組

[2017/03/28]
在 2014年 3月曾寫過一篇「Raspberry Pi 筆記(十五):超音波測距離Raspberry」,將 Pi 連接超音波模組,測試一下實際的距離與感應測得的數據差多少,實測的結果誤差不到1公分。

最近繼續研究 Pi 跟 Arduino,也發現另有一個超音波測距的模組,HC-SR04,我改用 Arduino 來連接這個模組,也寫程式測試一下兩者得到的結果是否相同。

[超音波測距 HC-SR04]

模組工作原理:
• 採用I/O觸發測距,給至少為10us的高電位信號
• 模組自動發送 8個 40KHZ的方波,自動檢測是否有信號返回
• 有信號返回,通過I/O輸出一高電位,高電位持續的時間就是超聲波從發射到返回的時間
• 測試距離 =(高電位時間 x 聲速(340M / S))/ 2

[技術規格]
• 電源:DC5V/2mA
• 輸出電位( 1/ 0):5V/ 0V
• 精度:3mm
• 距離範圍:2 ~ 450cm
• 有效的角度:<15℃
• 觸發輸入信號:10uS TTL pulse
• ECHO輸出信號: Input TTL lever signal and the range in proportion
• 接線方式:VCC、trig (控制端)、echo (接收端)、GND

[材料]

• Arduino Uno  x 1
• HC-SR04測距模組  x1
• 連接線 x 4條

[接線圖]


• HC-SR04測距模組連接線路
HC-SR04 測距模組
Arduino
1 - VCC
VCC
2 - Trig – Trigger
Pin 12
3 - Echo
Pin 11
4 - GND
GND

[程式一]

以下先不呼叫函式,直接以音波在空氣中傳遞的大約速度,算出來回測得的時間,乘以空氣中傳遞聲音的速度,算出距離。程式中有一行 cm = (duration/2) / 29.1,各位會不會覺得奇怪,為什麼要除以 29.1 ? 那是因為在攝氏零度之海平面音速約為331.5公尺/秒,每升高1攝氏度,音速就增加0.607公尺/秒,可以列出一個公式:

•  音速 c = 331.5 + 0.607 * t  (其中 t 為攝氏溫度)。

    例: 攝氏20度時的音速約為: 331.5 + 0.607*20 = 343.64 公尺/秒

•  音速公尺/秒 換算成 公分/微秒:343.64 * 100 / 1000000 = 0.034364 公分/微秒,亦即

    音速每公分需要29.1 微秒:  1 / 0.034364 = 29.1 微秒/公分

    超音波發射的距離為來回,因此單程距離 = 時間差 / 2  再除以  29.1 微秒 / 公分,同樣的如果要換算成英吋,只要將 29.1 再乘以 2.54 即可。來看看程式的內容:
int trigPin = 12;                  //Trig Pin
int echoPin = 11;                  //Echo Pin
long duration, cm, inches;
 
void setup() {
  Serial.begin (9600);             // Serial Port begin
  pinMode(trigPin, OUTPUT);        //Define inputs and outputs 
  pinMode(echoPin, INPUT);
}
 
void loop()
{
  digitalWrite(trigPin, LOW);
  delayMicroseconds(5);
  digitalWrite(trigPin, HIGH);     // 給 Trig 高電位,持續 10微秒
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  pinMode(echoPin, INPUT);             // 讀取 echo 的電位
  duration = pulseIn(echoPin, HIGH);   // 收到高電位時的時間
 
  cm = (duration/2) / 29.1;         // 將時間換算成距離 cm 或 inch  
  inches = (duration/2) / 74; 

  Serial.print("Distance : ");  
  Serial.print(inches);
  Serial.print("in,   ");
  Serial.print(cm);
  Serial.print("cm");
  Serial.println();
  
  delay(250);
}

[程式二]

網友將上述計算等方式,寫成一個函式,比較著名的是 NewPing,可以到 這裡 下載最新的函式庫,放到 Arduino 的預設 Libraries目錄,即可呼叫該函式,程式如下:
#include <NewPing.h>
#define TRIG_PIN    12          // trigger Pin
#define ECHO_PIN    11          // Echo Pin
#define MAX_DISTANCE 200        // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);    // 設定 NewPing 物件,並給與最遠測試距離

void setup() {
  Serial.begin(115200);         // 開啟串列埠顯示 ping 的距離值
}

void loop() {
  delay(50);                        // 等待 50 毫秒,需大於前程式說明的 29 秒
  unsigned int uS = sonar.ping();   // 送出 ping,並取得微秒 microseconds(uS) 時間
  Serial.print("Ping: ");
  Serial.print(sonar.convert_cm(uS));    // 換算時間為公分,如顯示 0,表示超出距離範圍
  Serial.println("cm");
}

[測試結果]

測試的結果還蠻正確的,跟規格提供的誤差值3mm差不多。接下來就要將 HC-SR04接到小車上去,看看遇到障礙物時,是否能自動轉彎或倒退。

[參考資料]

• Tim Eckel / Arduino New Ping:NewPing Arduino Library for Arduino
• Arduino Forum:NewPing Library Project Homepage
• Random Nerd Tutorials:Complete Guide for Ultrasonic Sensor HC-SR04
• 維基百科:音速
Share on Google Plus
    Blogger Comment
    Facebook Comment

0 意見 :

張貼留言