2017年11月6日 星期一

Arduino 超音波模組測試 (二) : 使用 NewPing 函式庫

這幾天在翻閱楊佩璐寫的 "跨入Maker物聯網時代 : 誰都可以用Arduino" 一書時, 在 12.2 節看到其超音波測試範例使用 NewPing 函式庫, 記得去年大概這個時候我也做過 Arduino 的超音波測試, 當時是依據聲波原理使用 pulseIn() 等函式土法煉鋼計算偵測的距離, 參考 :

Arduino 超音波模組測試

今天換個口味, 改用 NewPing 函式庫重新測試超音波模組 HC-SR04, 這是作者 Tim Eckel
因為對傳統的作法不滿意而撰寫的改進版, 參考 :

http://playground.arduino.cc/Code/NewPing

NewPing 函式庫下載網址 :

https://bitbucket.org/teckel12/arduino-new-ping/downloads/

解壓縮後整個目錄複製到 Arduino IDE 安裝目錄的 libraries 目錄下, 重啟 IDE 即可.

使用前須先建立 NewPing 物件 :

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);

三個傳入參數都是整數 , TRIGGER_PIN 是 HC-SR04 的 Trig 腳與 Arduino  相連的 DIO 腳位; ECHO_PIN 是 Echo 腳與 Arduino  相連的 DIO 腳位; MAX_DISTANCE 則是最遠的偵測距離, 一般是 HC-SR04 是 400 cm, 不過實測並沒有這麼遠, 大約 200 cm 而已.

NewPing 函式庫提供之函數如下 :

 函數 說明
 ping() 送出偵測訊號, 若收到回應傳回回應時間 (毫秒), 否則傳回 0.
 ping_in() 送出偵測訊號, 若收到回應傳回距離 (英吋), 否則傳回 0.
 ping_cm() 送出偵測訊號, 若收到回應傳回距離 (公分), 否則傳回 0.
 ping_median([iterations])  重複送出偵測訊號 (預設 5 次), 傳回回應時間之中數 (微秒).
 convert_in(echoTime) 傳入毫秒數傳回距離 (英吋)
 convert_cm(echoTime) 傳入毫秒數傳回距離 (公分)
 ping_timer(func) 送出偵測訊號, 並呼叫 func 函數以檢查收到回應.
 check_timer() 檢查是否在指定距離內收到回應.
 timer_us(freq, func) 啟動計時器每 freq 微秒呼叫 func 函數
 timer_ms(freq, func) 啟動計時器每 freq 毫秒呼叫 func 函數
 timer_stop() 停止計時器.

常用的函數是 ping_cm(), ping_median(), convert_cm() 等. 注意, 有整數傳回值者型態為 unsigned int.


測試 1 :  測試距離 (公分)

#include <NewPing.h>

#define TRIGGER_PIN  5
#define ECHO_PIN     6
#define MAX_DISTANCE 200

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);

void setup() {
  Serial.begin(9600);
  }

void loop() {
  Serial.print("Ping: ");
  Serial.print(sonar.ping_cm());  //傳回距離 (公分)
  Serial.println("cm");
  delay(500);
  }

少了計算程序真的簡單不少, 序列埠監控視窗輸出如下 :

Ping: 5cm
Ping: 5cm
Ping: 5cm
Ping: 5cm
Ping: 5cm
Ping: 5cm
Ping: 5cm
Ping: 5cm
Ping: 23cm
Ping: 16cm
Ping: 13cm
Ping: 8cm
Ping: 12cm
Ping: 101cm
Ping: 113cm
Ping: 55cm

可知當偵測距離變化時, 即時的傳回距離變化大, 比較好的方法是用 ping_median() 取得多次偵測的中數 (微秒), 再呼叫 convert_cm() 轉成公分, 如下列測試 2 :


測試 2 :  測試距離 (公分, 傳回多次偵測回應時間之中數) 

#include <NewPing.h>

#define TRIGGER_PIN  5
#define ECHO_PIN     6
#define MAX_DISTANCE 200

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);

void setup() {
  Serial.begin(9600);
  }

void loop() {
  Serial.print("Ping: ");
  unsigned int us=sonar.ping_median();     //傳回 5 次偵測的回應時間中數 (微秒)
  Serial.print(sonar.convert_cm(us));         //將回應時間 (微秒) 轉成距離 (公分)
  Serial.println("cm");
  delay(500);
  }

沒有留言 :