您好,登錄后才能下訂單哦!
樹莓派怎樣進行超聲波測距自動避障,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
超聲波測距的原理很簡單,發射一個聲波,反彈回來,然后接受反彈回來的這個聲波。 利用這個時間差,就可以算出距離了。 首先,連接超聲波模塊,我的連接在GPIO20和GPIO21上,所以相應的代碼如下
# 超聲波引腳 TRIG = 20 ECHO = 21
TRIG這個名稱也可以換,但是模塊上用的這個名字,用這個更好記憶。 TRIG負責發射超聲波,ECHO負責接收超聲波。
GPIO.output(TRIG, 0)
很多在后面追加了如下代碼:
time.sleep(0.000002)
應該是為了防止錯誤,因為緊接著,就需要把發射端置為高電平。
GPIO.output(TRIG, 1) time.sleep(0.00001) GPIO.output(TRIG, 0)
一定要 用GPIO.output(TRIG, 0)來把超聲波發射關閉,否則將會一直發射,也就沒有辦法測距了。 現在發射結束。
while GPIO.input(ECHO) == 0: pass emitTime = time.time() while GPIO.input(ECHO) == 1: pass acceptTime = time.time()
通過該代碼,獲取ECHO的狀態,一開始發射的時候,ECHO輸入為低電平,此時獲取一個時間emitTime,發射結束以后,接收啟動,接收到信號,獲得一個時間 acceptTime。
totalTime = acceptTime - emitTime distanceForReturn = totalTime * 340 / 2 * 100
這里之所以乘以100,是因為獲得的距離是微米,乘以100就是厘米了。
現在把上面的代碼整合起來,放在一個distance函數里面,并且返回距離的值。 完整代碼如下:
# 超聲波測距函數 def distance(): GPIO.output(TRIG, 0) time.sleep(0.000002) GPIO.output(TRIG, 1) time.sleep(0.00001) GPIO.output(TRIG, 0) while GPIO.input(ECHO) == 0: pass emitTime = time.time() while GPIO.input(ECHO) == 1: pass acceptTime = time.time() totalTime = acceptTime - emitTime distanceForReturn = totalTime * 340 / 2 * 100 return distanceForReturn
拿到了距離,需要讓超聲波按照要求不斷發射和接收,小車也需要做出相應的反應,因此還需要一個循環的函數。 代碼很難用文字解釋,但是很好理解。如下:
def loop(): while True: dis= distance() if dis<40: while dis<40: backword(50, 0.2) dis=distance() else: forward(50, 0)
if __name__ == '__main__': try: forward(50, 0) loop() except KeyboardInterrupt: GPIO.cleanup()
forward()和backword()等函數均是之前定義的小車運動的函數。 以下是整個文件的所有代碼:
import time # 綁定對應的引腳,來自于圖紙 PWMA = 18 AIN1 = 22 AIN2 = 27 PWMB = 23 BIN1 = 25 BIN2 = 24 # 超聲波引腳 TRIG = 20 ECHO = 21 GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) # 設置引腳為輸出 GPIO.setup(PWMA, GPIO.OUT) GPIO.setup(AIN1, GPIO.OUT) GPIO.setup(AIN2, GPIO.OUT) GPIO.setup(PWMB, GPIO.OUT) GPIO.setup(BIN1, GPIO.OUT) GPIO.setup(BIN2, GPIO.OUT) GPIO.setup(TRIG, GPIO.OUT) GPIO.setup(ECHO, GPIO.IN) # 電機 leftMotor = GPIO.PWM(PWMA, 100) rightMotor = GPIO.PWM(PWMB, 100) leftMotor.start(0) rightMotor.start(0) ##小車的前進函數 def forward(speed, runtime): leftMotor.ChangeDutyCycle(speed) GPIO.output(AIN1, True) # AIN1高電平則正轉 GPIO.output(AIN2, False) # 如果為True則翻轉 rightMotor.ChangeDutyCycle(speed) GPIO.output(BIN1, True) GPIO.output(BIN2, False) time.sleep(runtime) # 維持狀態的時間,如果不給命令執行其他,將會繼續執行 # 后退函數 def backword(speed, backtime): leftMotor.ChangeDutyCycle(speed) GPIO.output(AIN2, True) GPIO.output(AIN1, False) rightMotor.ChangeDutyCycle(speed) GPIO.output(BIN2, True) GPIO.output(BIN1, False) time.sleep(backtime) # 左轉彎函數 def turnLeft(speed, lefttime): leftMotor.ChangeDutyCycle(speed) GPIO.output(AIN1, False) GPIO.output(AIN2, True) rightMotor.ChangeDutyCycle(speed) GPIO.output(BIN1, True) GPIO.output(BIN2, False) time.sleep(lefttime) # 右轉彎函數 def turnRight(speed, righttime): leftMotor.ChangeDutyCycle(speed) GPIO.output(AIN1, True) GPIO.output(AIN2, False) rightMotor.ChangeDutyCycle(speed) GPIO.output(BIN1, False) GPIO.output(BIN2, True) time.sleep(righttime) # 超聲波測距函數 def distance(): GPIO.output(TRIG, 0) time.sleep(0.000002) GPIO.output(TRIG, 1) time.sleep(0.00001) GPIO.output(TRIG, 0) while GPIO.input(ECHO) == 0: pass emitTime = time.time() while GPIO.input(ECHO) == 1: pass acceptTime = time.time() totalTime = acceptTime - emitTime distanceForReturn = totalTime * 340 / 2 * 100 return distanceForReturn def loop(): while True: dis= distance() if dis<40: while dis<40: backword(50, 0.2) dis=distance() else: forward(50, 0) if __name__ == '__main__': try: forward(50, 0) loop() except KeyboardInterrupt: GPIO.cleanup()``` 這樣,遇到障礙物,就會后退。通過轉彎可以躲避障礙物,這里沒有寫躲避的代碼。其實就是轉向就可以了。
看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。