树莓派怎样进行超声波测距自动避障

树莓派怎样进行超声波测距自动避障,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

超声波测距的原理很简单,发射一个声波,反弹回来,然后接受反弹回来的这个声波。 利用这个时间差,就可以算出距离了。 首先,连接超声波模块,我的连接在GPIO20和GPIO21上,所以相应的代码如下

# 超声波引脚
TRIG = 20
ECHO = 21

TRIG这个名称也可以换,但是模块上用的这个名字,用这个更好记忆。 TRIG负责发射超声波,ECHO负责接收超声波。

1、初始化超声波模块,也就是把它不让他发射,置于低电平

  GPIO.output(TRIG, 0)

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

time.sleep(0.000002)

应该是为了防止错误,因为紧接着,就需要把发射端置为高电平。

2、发射超声波

GPIO.output(TRIG, 1)
time.sleep(0.00001)
GPIO.output(TRIG, 0)

一定要 用GPIO.output(TRIG, 0)来把超声波发射关闭,否则将会一直发射,也就没有办法测距了。 现在发射结束。

3、接收超声波

while GPIO.input(ECHO) == 0:
    pass
emitTime = time.time()
while GPIO.input(ECHO) == 1:
    pass
    acceptTime = time.time()

通过该代码,获取ECHO的状态,一开始发射的时候,ECHO输入为低电平,此时获取一个时间emitTime,发射结束以后,接收启动,接收到信号,获得一个时间 acceptTime。

4、计算距离

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

这里之所以乘以100,是因为获得的距离是微米,乘以100就是厘米了。

5、整合代码

现在把上面的代码整合起来,放在一个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

6、循环发射超声波并检测距离

拿到了距离,需要让超声波按照要求不断发射和接收,小车也需要做出相应的反应,因此还需要一个循环的函数。 代码很难用文字解释,但是很好理解。如下:

def loop():
    while True:
        dis= distance()
        if dis<40:
            while dis<40:
                backword(50, 0.2)
                dis=distance()
        else:
            forward(50, 0)

7、运行函数

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

    except KeyboardInterrupt:
        GPIO.cleanup()

8、写在文章外

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()```
这样,遇到障碍物,就会后退。通过转弯可以躲避障碍物,这里没有写躲避的代码。其实就是转向就可以了。

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注亿速云行业资讯频道,感谢您对亿速云的支持。

原创文章,作者:kepupublish,如若转载,请注明出处:https://blog.ytso.com/206646.html

(0)
上一篇 2021年12月3日
下一篇 2021年12月3日

相关推荐

发表回复

登录后才能评论