[Embedded Development] Ultrasonic obstacle avoidance car based on Raspberry Pi (Python)

1. Module introduction and assembly

1.1 Required hardware
(1) Burned Raspberry Pi 4B
(2) Car frame (can be purchased online).
(3) DC motor *4: used to drive the trolley.
(4) L298N motor drive module: used to control the motor.
(5) Ultrasonic ranging module: used for real-time ranging to achieve autonomous obstacle avoidance.
(6) Other auxiliary devices: including charging treasure (powered by Raspberry Pi), dry battery pack (powered by motor) and some Dupont cables.
1.2 Overall structure
the whole frame

1.3 L298N motor drive module
This module is also called L298N double H-bridge DC motor drive module, and the four output ports (out1, out2, out3, out4) of the module are connected to the positive and negative poles of the DC motor respectively. The power supply ports (12V, GND) are respectively connected to the positive and negative poles of the battery pack. The four input ports (IN1, IN2, IN3, IN4) are respectively connected to GPIO ports 11, 12, 13, 15 of the Raspberry Pi.
L298N Motor Driver Module

L298N Motor Driver Module

The L298N module controls the steering of the motor through the level signals of the four input ports. Among them, IN1 and IN2 control out1 and out2 (that is, the left motor), and IN3 and IN4 control out3 and out4 (that is, the right motor). The following is the truth table for controlling the motor:

IN1 IN2 motor
0 0 stop
0 1 reverse
1 0 Forward
1 1 stop

1.4 Ultrasonic module
Connect the ultrasonic module TRIG and ECHO to GPIO29 and GPIO31 respectively, TRIG is responsible for transmitting ultrasonic waves, ECHO is responsible for receiving ultrasonic waves, VCC is connected to the Raspberry Pi 5V interface to power the module, and GND is connected to the Raspberry Pi GND interface. Use the time difference between transmission and reception to calculate distance.
Ultrasonic module
Ultrasonic module

2. Implement the code

2.1 Ultrasonic obstacle avoidance

#超声波测距函数
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 Complete code

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 Terminal operation test and summary

Transfer the Python code file to the Raspberry Pi, and use the PUTTY software to log in to the Raspberry Pi and compile and execute the program. The following figure shows the terminal running interface: Summary: After
Terminal running results
running the
program, the car can achieve simple obstacle avoidance, but only one ultrasonic wave is used. The ranging module has a large blind area, and multi-channel detection can be used to improve accuracy.

Guess you like

Origin blog.csdn.net/weixin_51450101/article/details/123365969