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