树莓派怎样进行超声波测距自动避障,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。
超声波测距的原理很简单,发射一个声波,反弹回来,然后接受反弹回来的这个声波。 利用这个时间差,就可以算出距离了。 首先,连接超声波模块,我的连接在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进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。