基礎教程10 Arduino 超聲波測距

基礎教程10 Arduino 超聲波測距

來自專欄 Arduino 魔法書6 人贊了文章

我是潘,曾經是個工程師。這是為 Ardui.Co 製作的 「Arduino 公開課」 系列的入門教程。上一課介紹了溫濕度模塊和庫的使用,現在我們用超聲波模塊測量距離。有任何疑問請在評論區提出,我會逐一回答。

超聲波測距的原理是發射聲波,聲波遇到物體反射,模塊接收,得出時間差,然後根據聲速計算出物體距離。其應用非常之廣,如現場測距,無人機避障、汽車雷達等,而且價格極為低廉,庫成熟,是最常用的模塊。這次我們介紹的是 HC-SR04、HC-SR05:

該模塊一共有Vcc、GND、Trig 和 Echo,4個引腳。Arduino 通過 Trig 引腳給模塊,不少於10us 數字信號(高電平),觸發模塊發射出 40KHz 的超聲波,接收到返回聲波後,Echo 輸出高電平,根據觸發和輸出的時間差,就可以換算出距離。但我們不需要設計換算程序,因為這個模塊有現成的庫可以用,調用庫里的方法即可。模塊參數如下:

測量距離:2 ~ 450cm

解析度:0.3cm

測量頻率:40Hz(最快每25ms測量一次)

測量角度:15deg

工作電壓:4.5 ~ 5.5V

工作電流:10 ~ 40mA

該模塊實際測量距離約為 200cm,而且經常會有嚴重的漂移現象,因此建議多次採樣,使用中位數,可以保證測量正確。

接線方式很簡單:

開發程序之前,我們需要先下載 NewPing.h 庫,這個庫不在官方的索引裡面,因此需要先下載:NewPing_v1.8

下載後不要急著解壓,在 IDE 界面頂部菜單,選擇「項目」中的「載入庫」,然後點擊 「添加一個.zip庫」 即可載入。我們在編寫程序前,同樣「載入庫」中,選擇插入需要的庫函數,IDE就會自動插入:

/* 作者:Ardui.Co 效果:超聲波測距 版本:1.0 更新時間:2017年2月14日*/#include <NewPing.h>#define TRIGGER_PIN 12 // 宏定義12號數字埠為觸發#define ECHO_PIN 11 // 宏定義11號數字埠為接收模塊反饋信號#define MAX_DISTANCE 200 //宏定義模塊的最大測量距離,規格標450cm,但實測一般為200cmNewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); //聲明模塊的參數void setup() { Serial.begin(115200); // 設置串口的波特率,可以改為9600}void loop() { delay(500); // 每次測量的時間間隔,模塊規格為40Hz,因此最小為25ms,但一般不少於30ms Serial.print("Ping: "); Serial.print(sonar.ping_cm()); // 調用庫裡面的 ping_cm() 方法,直接輸出距離 Serial.println("cm");}

上面是常規的接線方式,但 NewPing.h 是個非常強大的庫,為節省 Arduino 埠,我們還可以將 Trig 和 Echo 接在一起,只用一條數據引線傳輸兩種信號,只要簡單修改下程序:

/* 作者:Ardui.Co 效果:超聲波測距模塊,使用單線連接 版本:1.0 更新時間:2017年1月13日*/#include <NewPing.h>#define PING_PIN 12 // 宏定義12號數字埠為觸發和接收埠#define MAX_DISTANCE 200 //宏定義模塊的最大測量距離,規格標450cm,但實測一般為200cmNewPing sonar(PING_PIN, PING_PIN, MAX_DISTANCE); //聲明模塊的參數,注意Trig和Echo都是同一個埠void setup() { Serial.begin(115200); // 設置串口的波特率}void loop() { delay(500); // 每次測量的時間間隔,模塊規格為40Hz,因此最小為25ms,但一般不少於30ms Serial.print("Ping: "); Serial.print(sonar.ping_cm()); // 調用庫裡面的 ping_cm() 方法,直接輸出距離 Serial.println("cm");}

如果測量距離超出了限定範圍200cm,程序會怎麼處理?答案是輸出 0。

由於超聲波測量容易受到環境因素影響,模塊漂移幾率較大,我們可以多次採樣,然後取中位數(思考一下:為什麼不是平均值?)避免忽大忽小的問題,NewPing.h 已經提供了 ping_median() 方法,但輸出的是時間(毫秒),所以我們還要用到一個轉換方法:

/* 作者:Ardui.Co 效果:超聲波測距模塊,使用單線連接 版本:1.0 更新時間:2017年1月13日*/#include <NewPing.h>#define PING_PIN 12 // 宏定義12號數字埠為觸發和接收埠#define MAX_DISTANCE 200 //宏定義模塊的最大測量距離,規格標450cm,但實測一般為200cmNewPing sonar(PING_PIN, PING_PIN, MAX_DISTANCE); //聲明模塊的參數,注意Trig和Echo都是同一個埠void setup() { Serial.begin(115200); // 設置串口的波特率}void loop() { delay(500); // 每次測量的時間間隔,模塊規格為40Hz,因此最小為25ms,但一般不少於30ms Serial.print("Ping: "); int t = sonar.ping_median(5, 200);//測量5次並設定最大距離為200cm,然後取中位數輸出 Serial.print(sonar.convert_cm(t)); // 使用convert_cm()方法,將時間轉換為距離 Serial.println("cm");}

NewPing.h 還提供了程序中斷、積累計時等方法,在挑戰篇中我們會用到。另外,閱讀官方文檔也是一個重要的學習途徑:bitbucket.org/teckel12/


推薦閱讀:

北航單片機
FPGA學習(一)——產生頻率可控的正弦波
單片機小書0-意亂情迷
單片機常用名詞概念解析(不記得趕緊背)
雲龍51單片機視頻教程,(零基礎手把手教你學單片機)

TAG:開源硬體 | 單片機 | Arduino |