2013年9月25日 星期三

Arduino範例14:測試超音波模組(HC-SR04)

這次要使用的超音波模組是HC-SR04,這是網拍上最常見的模組。
另外有人可能也會買到3 Pin的模組 (我查不到型號),那就是trig與echo同一個Pin。
回到HC-SR04來看,我找到它的型錄,了解一下它的用法:

Ultrasonic ranging module HC - SR04 provides 2cm - 400cm non-contact
measurement function, the ranging accuracy can reach to 3mm. The modules
includes ultrasonic transmitters, receiver and control circuit. The basic principle
of work:
  • Using IO trigger for at least 10us high level signal. 
  • The Module automatically sends eight 40 kHz and detect whether there is a pulse signal back.
  • IF the signal back, through high level , time of high output IO duration is the time from sending ultrasonic to returning.
  • Test distance = (high level time×velocity of sound (340M/S) / 2. 
  • When tested objects, the range of area is not less than 0.5 square meters and the plane requests as smooth as possible, otherwise ,it will affect the results of measuring.
  • Suggest to use over 60ms measurement cycle, in order to prevent trigger signal to the echo signal.

給trig pin一個10 us TTL pluse, 模組會發射8個40k Hz的聲波出去,然後量測訊號是否回來。如果有收到TTL的高電位訊號,那Echo會送出超音波來回的時間,使用者再自己計算音速換算距離。也就是「距離(cm) = 時間(us) / 2(來回) /29.1 (m/s轉換cm/us)」。其它要注意的是量測物體最好大於0.5公尺平方,而trigger時間最好大於60ms,以免trig與echo干擾。


註:什麼叫TTL pulse可參考以下網址
http://digital.ni.com/public.nsf/allkb/ACB4BD7550C4374C86256BFB0067A4BD

接線圖
接線的方法很簡單,就把 Trig 接上要送 10 us 的Pin腳。Echo 接到要收訊號的 Pin腳。



至於Pin 6要怎麼量測pulse的時間長度呢?在Arduino裡有現成的指令"pulseIn ( )",說明如下:

pulseIn ( ) :讀取一個針腳的脈衝時間(HIGH或LOW)。
例如,如果value是HIGH,pulseIn ( ) 會等待引腳變為HIGH,開始計時,再等待引腳變為LOW並停止計時。返回脈衝的長度,單位微秒。如果在指定的時間內無脈衝,函數返回0。此函數的計時功能由經驗決定,長時間的脈衝計時可能會出錯。建議計時範圍從10微秒至3分鐘。(1秒=1000毫秒=1000000微秒)

Code
const int trig = 5;
const int echo = 6;
const int inter_time = 1000;
int time = 0;

void setup() {
  Serial.begin(9600);
  pinMode (trig, OUTPUT);
  pinMode (echo, INPUT);
}

void loop() {
  float duration, distance;
  digitalWrite(trig, HIGH);
  delayMicroseconds(1000);
  digitalWrite(trig, LOW);
  duration = pulseIn (echo, HIGH);
  distance = (duration/2)/29;
  Serial.print("Data:");
  Serial.print (time/1000);
  Serial.print(", d = ");
  Serial.print(distance);
  Serial.println(" cm");
  time = time + inter_time;
  delay(inter_time);
}

16 則留言:

  1. 回覆
    1. 我不確定我是否懂你的問題,您指的是什麼速度?反應速度嗎?還是越遠需要的時間越久?

      刪除
  2. 抱歉請教一下, distance = (duration/2)/29; 中 的29是怎麼算出的呢?

    是由 uS / 58 = cm 去單位換算嗎??

    回覆刪除
    回覆
    1. 是因為這樣嗎?
      duration/(2*340*100/1000000) = ( duration/2 ) *0.034 = ( duration/2 ) / (29.4117647059)

      刪除
    2. 上一個打錯了
      (duration/2)*340*100/1000000 = ( duration/2 ) * 0.034 = ( duration/2 ) / (29.4117647059)

      刪除
    3. 是的,是把x340 變成倒數

      刪除
  3. 請問:
    除上1000000=1us 是否少個零呢?
    因為我除上10us 才等於 0.034

    回覆刪除
  4. 不好意思 我能請教一下
    HC-SR04使用到arduino sensor shield v5.0
    的腳位是要怎麼接
    有特定的接法嗎 ?

    回覆刪除
    回覆
    1. 倒是沒有特定的接法,只要trigger跟echo有跟程式裡對應起來就好。

      刪除
  5. 作者已經移除這則留言。

    回覆刪除
  6. 想請問一下如果用多個超音波
    他們的trig可以接再一起嗎 (同時發送)
    在不同的echo接收
    (因為需要省arduino角位)

    回覆刪除
  7. 請問變數time的意思是總共跑了多久嗎?

    回覆刪除
  8. 你好 我想請問那如果我要改成測速呢?
    距離/時間是速度
    那我要用哪一個計算出來的時間和所測到的距離相除呢?

    回覆刪除
  9. 請問echo輸出的訊號是電壓值還是時間差?

    回覆刪除
  10. 請問一下,超音波模組的響應時間是多少?

    回覆刪除
  11. 作者已經移除這則留言。

    回覆刪除