溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

樹莓派怎樣進行超聲波測距自動避障

發(fā)布時間:2021-11-19 18:38:36 來源:億速云 閱讀:137 作者:柒染 欄目:互聯(lián)網(wǎng)科技

樹莓派怎樣進行超聲波測距自動避障,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學(xué)習下,希望你能有所收獲。

超聲波測距的原理很簡單,發(fā)射一個聲波,反彈回來,然后接受反彈回來的這個聲波。 利用這個時間差,就可以算出距離了。 首先,連接超聲波模塊,我的連接在GPIO20和GPIO21上,所以相應(yīng)的代碼如下

# 超聲波引腳
TRIG = 20
ECHO = 21

TRIG這個名稱也可以換,但是模塊上用的這個名字,用這個更好記憶。 TRIG負責發(fā)射超聲波,ECHO負責接收超聲波。

1、初始化超聲波模塊,也就是把它不讓他發(fā)射,置于低電平

  GPIO.output(TRIG, 0)

很多在后面追加了如下代碼:

time.sleep(0.000002)

應(yīng)該是為了防止錯誤,因為緊接著,就需要把發(fā)射端置為高電平。

2、發(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é)束。

3、接收超聲波

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。

4、計算距離

 totalTime = acceptTime - emitTime
distanceForReturn = totalTime * 340 / 2 * 100

這里之所以乘以100,是因為獲得的距離是微米,乘以100就是厘米了。

5、整合代碼

現(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

6、循環(huán)發(fā)射超聲波并檢測距離

拿到了距離,需要讓超聲波按照要求不斷發(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)

7、運行函數(shù)

if __name__ == '__main__':
    try:
        forward(50, 0)
        loop()

    except KeyboardInterrupt:
        GPIO.cleanup()

8、寫在文章外

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è)資訊頻道,感謝您對億速云的支持。

向AI問一下細節(jié)

免責聲明:本站發(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)容。

AI