【嵌入式开发】基于树莓派实现超声波避障小车(Python)
目录
1. 模块介绍与组装
1.1 所需硬件
(1)烧制好的树莓派4B
(2)小车车架(可在网上购买)。
(3)直流电机*4:用于驱动小车行驶。
(4)L298N电机驱动模块:用于实现对电机的控制。
(5)超声波测距模块:用于实时测距,以实现自主避障。
(6)其余辅助器件:包括充电宝(树莓派供电)、干电池组(电机供电)及杜邦线若干。
1.2 整体结构
1.3 L298N电机驱动模块
该模块又叫L298N双H桥直流电机驱动模块,将模块的四个输出口(out1、out2、out3、out4)分别与直流电机正负极相连。供电口(12V、GND)分别与电池组正负极相连。四个输入口(IN1、IN2、IN3、IN4)分别与树莓派GPIO接口11、12、13、15相连。
L298N模块通过四个输入口电平信号的高低来实现对电机转向的控制。其中IN1、IN2控制out1、out2(即左侧电机),IN3、IN4控制out3、out4(即右侧电机)。下面是对电机进行控制的真值表:
IN1 | IN2 | 电机 |
---|---|---|
0 | 0 | 停止 |
0 | 1 | 反转 |
1 | 0 | 正转 |
1 | 1 | 停止 |
1.4 超声波模块
将超声波模块TRIG和ECHO分别连接到GPIO29和GPIO31上,TRIG负责发射超声波,ECHO负责接收超声波,VCC接树莓派5V接口以实现对模块的供电,GND接树莓派GND接口。利用发射和接收的时间差来计算距离。
2. 实现代码
2.1 超声波避障
#超声波测距函数
def Distance_Ultrasound():
GPIO.output(TRIG,GPIO.LOW) #输出口初始化置LOW(不发射)
time.sleep(0.000002)
GPIO.output(TRIG,GPIO.HIGH) #发射超声波
time.sleep(0.00001)
GPIO.output(TRIG,GPIO.LOW) #停止发射超声波
while GPIO.input(ECHO) == 0:
emitTime = time.time() #记录发射时间
while GPIO.input(ECHO) == 1:
acceptTime = time.time() #记录接收时间
totalTime = acceptTime - emitTime #计算总时间
distanceReturn = totalTime * 340 / 2 * 100 #计算距离(单位:cm)
return distanceReturn #返回距离
#避障函数
def Obstacle_Avoidance():
while True:
dis= Distance_Ultrasound()
print("距离 ",dis,"cm")
if dis<30: #距离小于30cm时启动避障程序
while dis<30:
Back_time(0.5) #距离小于30cm时后退0.5s
dis=Distance_Ultrasound()
print("距离 ",dis,"cm")
Left_time(1.5) #左转1.5s
Forward() #继续前进
time.sleep(0.5)
2.2 完整代码
import RPi.GPIO as GPIO #引入RPi.GPIO库函数命名为GPIO
import time #引入计时time函数
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM) #将GPIO编程方式设置为BCM模式,基于插座引脚编号
#接口定义
TRIG = 5 #将超声波模块TRIG口连接到树莓派Pin29
ECHO = 6 #将超声波模块ECHO口连接到树莓派Pin31
INT1 = 17 #将L298 INT1口连接到树莓派Pin11
INT2 = 18 #将L298 INT2口连接到树莓派Pin12
INT3 = 27 #将L298 INT3口连接到树莓派Pin13
INT4 = 22 #将L298 INT4口连接到树莓派Pin15
#输出模式
GPIO.setup(TRIG,GPIO.OUT)
GPIO.setup(ECHO,GPIO.IN)
GPIO.setup(INT1,GPIO.OUT)
GPIO.setup(INT2,GPIO.OUT)
GPIO.setup(INT3,GPIO.OUT)
GPIO.setup(INT4,GPIO.OUT)
#一直前进函数
def Forward():
GPIO.output(INT1,GPIO.LOW)
GPIO.output(INT2,GPIO.HIGH)
GPIO.output(INT3,GPIO.LOW)
GPIO.output(INT4,GPIO.HIGH)
#后退指定时间函数
def Back_time(time_sleep):
GPIO.output(INT1,GPIO.HIGH)
GPIO.output(INT2,GPIO.LOW)
GPIO.output(INT3,GPIO.HIGH)
GPIO.output(INT4,GPIO.LOW)
time.sleep(time_sleep)
#左转指定时间函数
def Left_time(time_sleep):
GPIO.output(INT1,GPIO.LOW)
GPIO.output(INT2,GPIO.LOW)
GPIO.output(INT3,GPIO.LOW)
GPIO.output(INT4,GPIO.HIGH)
time.sleep(time_sleep)
#停止函数
def Stop():
GPIO.output(INT1,GPIO.LOW)
GPIO.output(INT2,GPIO.LOW)
GPIO.output(INT3,GPIO.LOW)
GPIO.output(INT4,GPIO.LOW)
#超声波测距函数
def Distance_Ultrasound():
GPIO.output(TRIG,GPIO.LOW) #输出口初始化置LOW(不发射)
time.sleep(0.000002)
GPIO.output(TRIG,GPIO.HIGH) #发射超声波
time.sleep(0.00001)
GPIO.output(TRIG,GPIO.LOW) #停止发射超声波
while GPIO.input(ECHO) == 0:
emitTime = time.time() #记录发射时间
while GPIO.input(ECHO) == 1:
acceptTime = time.time() #记录接收时间
totalTime = acceptTime - emitTime #计算总时间
distanceReturn = totalTime * 340 / 2 * 100 #计算距离(单位:cm)
return distanceReturn #返回距离
#避障函数
def Obstacle_Avoidance():
while True:
dis= Distance_Ultrasound()
print("距离 ",dis,"cm")
if dis<30: #距离小于30cm时启动避障程序
while dis<30:
Back_time(0.5) #距离小于30cm时后退0.5s
dis=Distance_Ultrasound()
print("距离 ",dis,"cm")
Left_time(1.5) #左转1.5s
Forward() #继续前进
time.sleep(0.5)
print("超声波避障系统运行中,按Ctrl+C退出...")
try:
Forward() #初始状态为前进
Obstacle_Avoidance()
except KeyboardInterrupt:
Stop()
2.4 终端运行测试及总结
将Python代码文件传输至树莓派中,可利用PUTTY软件登录树莓派并编译执行程序,下图为终端运行界面:
总结:
运行程序后,小车能实现简单的避障,但只采用一个超声波测距模块,存在较大的盲区,可采用多路探测来提高准确度。