首先來看一下這個測距模塊長什麼樣子: 就是HC-SR04模塊。 這個模塊有四個引腳,分別是Vcc(高電平),GND(低電平),Trig(觸發測距)以及Echo(返回測距結果)。 那麼這個模塊怎麼使用呢,資料上的說明是這樣的: 首先給出時序圖: 從上面的步驟可以看出,我們只需要測量Echo腳為高電平的 ...
首先來看一下這個測距模塊長什麼樣子:
就是HC-SR04模塊。
這個模塊有四個引腳,分別是Vcc(高電平),GND(低電平),Trig(觸發測距)以及Echo(返回測距結果)。
那麼這個模塊怎麼使用呢,資料上的說明是這樣的:
首先給出時序圖:
- 在Vcc和GND的電平都正確的時候,如果想要讓模塊開始測距,需要給Trig腳一個不小於10us的高電平脈衝。
- 發出這個脈衝之後,模塊會自動將Echo腳設置為高電平,並且模塊會在這個時候發出超聲波脈衝(圖上說明是8個連續的脈衝,這個脈衝數字我們不用管,反正就是發出了脈衝)。
- 當超聲波遇到障礙物反彈回來之後,會被模塊接受到。接收到之後Echo腳會自動變成低電平,從而完成一次測距。
從上面的步驟可以看出,我們只需要測量Echo腳為高電平的時間,然後乘上聲速/2就可以了(除2是因為超聲波來回了一趟,路程為距離的兩倍)
我們是在空氣中測速的,聲波為340m/s。
根據上面的過程,可以寫出代碼如下:
1 import RPi.GPIO as GPIO 2 import time 3 4 Vcc_Pin=33 5 Echo_Pin=37 6 Trig_Pin=35 7 8 def initDist(): 9 GPIO.setup(Vcc_Pin,GPIO.OUT,initial=GPIO.HIGH) 10 GPIO.setup(Trig_Pin,GPIO.OUT,initial=GPIO.LOW) 11 GPIO.setup(Echo_Pin,GPIO.IN) 12 13 def _getDist(): 14 time.sleep(0.1) 15 GPIO.output(Trig_Pin,GPIO.HIGH) 16 time.sleep(0.00002) #這裡延時了20us,只要大於10us即可 17 GPIO.output(Trig_Pin,GPIO.LOW) 18 while GPIO.input(Echo_Pin)==GPIO.LOW: #等待Echo腳為高電平 19 pass 20 #print("echo gpio is high") 21 t=time.time() #開始計數 22 while GPIO.input(Echo_Pin)==GPIO.HIGH: #等待Echo腳為低電平 23 pass 24 #print("echo gpio is low") 25 t=time.time()-t #計數停止 26 #print(t,"s passed") 27 if t<=0: 28 print("Can't get distance") 29 return -1 30 return t*340/2 #返回距離(m為單位) 31 32 def getDist(): 33 dist=[] 34 print("measuring") 35 for i in range(0,5): 36 temp=_getDist() 37 if not temp==-1: 38 dist.append(temp) 39 sum=0 40 for i in dist: 41 sum+=i 42 return sum/len(dist) 43 44 if __name__=='__main__': 45 GPIO.setmode(GPIO.BOARD) 46 initDist() 47 str="you can input q to quit,or press other key to get a distance" 48 r=input(str) 49 try: 50 while not r =='q': 51 print(getDist()*100,"cm") 52 time.sleep(1) #延時1s 53 r=input(str) 54 except KeyboardInterrupt: 55 pass 56 GPIO.cleanup()
8~11行的initDist()函數初始化模塊的引腳
13~30行_getDist()函數進行一次測距(其實這裡已經獲得了一次測量的距離了,但是為了防止數據偏差較大,後面還使用了getDist()函數取了平均值)
32~42行進行4次測距,並取平均值
44~56行main入口,當用戶輸入不為q的時候測距。測出的結果轉化為cm。
這裡14和52行的延時是為了模塊能夠反映過來。因為我在測試的時候發現不延時的話程式容易卡住。
具體的結果在這裡: