牟曉東
超聲波傳感器能檢測與前方障礙物間的距離,如果將它固定于360 度旋轉的舵機上持續采樣,就能將采樣獲取的數據繪制成雷達圖進行動態展示。
樹莓派3B+ 和古德微擴展板各一塊,HC-SR04 超聲波傳感器一個,4 路8 線電滑環一個,360 度舵機一個,紅色、綠色LED 燈各一支;還需要電烙鐵和熱熔槍各一把。
用熱熔槍將滑環中央的轉子底端與舵機輸出轉子進行固定,注意二者的中心點要盡量吻合,防止旋轉時偏心。再將滑環中央轉子的頂端與超聲波傳感器頂端固定好,也要中心對齊。接著,將滑環外圍的定子圈的四根線與古德微擴展板的20 號和21 號(共四個引腳)進行連接,紅線接電源正極VCC,黑線接地GND,橙紅色線接Trig 信號發射端,棕色線接Echo信號回聲端。滑環中央轉子4 根引線分別與超聲波傳感器的四個引腳進行對應連接(電烙鐵點錫);將舵機固定好之后,連接線插入擴展板的18 號引腳,注意黑色、紅色和棕黃色三根線分別與GND、VCC和信號控制D 端連接;然后,將紅色和綠色LED 燈按照“長腿正、短腿負”的規則分別插入擴展板的5 號和6 號引腳;最后,給樹莓派插入數據線,通電啟動操作系統(如圖1)。
(1)庫模塊的導入與變量初始化
首先, 導入GPIO Zero 、Matplot Lib等庫模塊: “from gpiozero import LED , Servo , Distance Sensor ”“ importnumpyasnp”“importmatplotlib”"impor tmatplotlib.pyplot as plt”和“importtime”; 然后進行LED 燈、舵機和超聲波傳感器實例的初始化操作:“ Red _ LED= LED ( 5 ) ”“ Green_LED=LED(6)”“servo=Servo(18)”和“sensor=DistanceSensor(echo=21,trigger=20,max_distance=4)”, 并且通過語句“servo.mid()”控制360 度舵機以中速帶動超聲波傳感器向一個方向開始旋轉;再設置雷達圖繪制畫布的寬度和高度,大小分別為8 和6(單位為英寸):“plt.figure(figsize=(8,6))”;建立變量ax,賦值為“plt.subplot(111,projection='polar')”, 作用是設置畫圖樣式為“極坐標”模式(Polar);建立變量theta, 賦值為“np.arange(0,2*np.pi,2*np.pi/30)”,通過調用Numpy 庫中的arange() 函數返回一個起點為0、終點為2Pi(360 度圓周)的等差數列,固定步長為2Pi/30;語句“plt.ion()”的作用是將figure 繪圖設置為交互模式;建立變量data,賦值為空列表“[]”,作用是存放超聲波傳感器每旋轉360 度一周掃描后檢測生成的若干個與前方障礙物的間距值。
(2)“whileTrue:”循環體
如果超聲波傳感器檢測的障礙間距值在安全范圍內(比如20cm),則控制綠色LED 燈常亮:“Green_LED.on()”;在每次旋轉360 度的過程中,需要獲取30 個值與之前產生的等差數列30 個刻度值對應:“for i in range(30):”; 建立變量distance,賦值為“round(sensor.distance,4)”, 獲取檢測到的障礙間距數據( 保留4位小數), 并且通過語句“print(i,distance)” 進行輸出監測; 在“if distance<=0.2:” 分支結構中, 如果條件成立則亮紅色LED 燈、關閉綠色LED 燈:“Red_LED.on()”“Green_LED.off()”, 持續時間為0.01 秒鐘:“time.sleep(0.01)”; 然后通過語句“data.append(distance)”, 將數據有序追加到data 列表中,再關閉紅色LED燈、打開綠色LED 燈:“Red_LED.off()”“Green_LED.on()”。

進入下一次循環(range),30次循環結束之后, 開始繪制雷達圖: 語句“ax.plot(theta,data,'o--',color='g',label='data',linewidth=1)”對極坐標進行數據設置,包括30 個0 至360 度的等差刻度值、30 個超聲波檢測障礙間距值(data 列表)、線的模式(虛線)、顏色(Green 綠色)和線寬(linewidth)等; 語句“ax.fill(theta,data,facecolor='g',alpha=0.15)” 是對30個障礙間距值與極坐標中心點圍成的封閉區域進行設置,包括填充顏色和透明度等;語句“plt.pause(0.1)”的作用是控制交互式繪圖過程中數據更新的預留時間緩沖,預防出現圖形不能及時刷新顯示的問題;語句“plt.cla()”的作用是清除當前活動軸的數據內容(相當于清空操作),語句“plt.show()”的作用是繪制顯示圖像,語句“data.clear()”的作用是清除data 列表中的當前數據,為下一次循環保存新數據“留空”。
將程序保存為Radar.py, 點擊“ 運行” 按鈕進行超聲波動態雷達的測試。超聲波傳感器在舵機的帶動下開始勻速旋轉,程序界面中也不斷有“00.2698”“23 0.3555”等信息出現,表示每次旋轉一周所監測到的30 個障礙間距值;同時,綠色LED 燈亮起,如果出現有近距離的障礙物(在20cm 范圍內),則會亮起紅色LED 燈。超聲波傳感器每旋轉一周,就會出現一個雷達極坐標圖,繪制有每個點所處的二維空間位置(角度值)和距離中心的半徑大小(障礙物間距值),同時在這些坐標點所包圍生成的封閉區域內,雷達圖是以一定透明度的綠色來展示的。隨著超聲波傳感器的不停旋轉,同時在其周圍變換出現各種障礙物,整個雷達圖也在不斷發生變化(如圖2)。
關注“壹零社”公眾號下載源代碼。