跑跑啦航模

树莓派超声波避障小车制作教程

一、项目概述

利用树莓派、HC-SR04超声波模块、L298N电机驱动板和两个直流减速电机制作自动避障小车。小车在前进过程中通过超声波检测前方障碍,当距离小于设定阈值时自动转向。


@@IMG@@b19-3.jpg@@/IMG@@

二、硬件清单

| 组件 | 数量 | 说明 |

|------|------|------|

| 树莓派4B/3B+ | 1 | 主控制器 |

| 智能小车底盘 | 1 | 带2个直流减速电机+2个万向轮 |

| L298N电机驱动模块 | 1 | 电机驱动 |

| HC-SR04超声波模块 | 1 | 障碍检测 |

| SG90舵机 | 1 | 超声波云台(可选) |

| 18650电池组 | 1 | 7.4V-12V供电 |

| 杜邦线 | 若干 | 连接线材 |

三、硬件接线

L298N驱动板接线:

| L298N | 树莓派GPIO | 功能 |

|-------|-----------|------|

| ENA | GPIO25 | 电机A使能 |

| IN1 | GPIO17 | 电机A方向1 |

| IN2 | GPIO18 | 电机A方向2 |

| ENB | GPIO24 | 电机B使能 |

| IN3 | GPIO22 | 电机B方向1 |

| IN4 | GPIO23 | 电机B方向2 |

| 12V | 电池正极 | 电机电源 |

| GND | 电池负极/树莓派GND | 共地 |

HC-SR04超声波接线:

| HC-SR04 | 树莓派GPIO |

|---------|-----------|

| VCC | 5V |

| Trig | GPIO20 |

| Echo | →分压→ GPIO21 |

| GND | GND |

分压电路: Echo输出5V,需用1kΩ+2kΩ电阻分压后接入GPIO21。

四、安装步骤

1. 组装底盘: 安装电机、万向轮、电池盒

2. 安装树莓派和驱动板: 使用铜柱固定

3. 安装超声波模块: 固定在小车前方,可使用支架调整角度

4. 连接电池: L298N供电接电池,树莓派供电通过降压模块从电池取电

五、完整代码

```python

import RPi.GPIO as GPIO

import time

# 引脚定义

MOTOR_A_EN = 25

MOTOR_A_IN1 = 17

MOTOR_A_IN2 = 18

MOTOR_B_EN = 24

MOTOR_B_IN3 = 22

MOTOR_B_IN4 = 23

TRIG = 20

ECHO = 21

SAFE_DISTANCE = 30 # 安全距离(cm)

GPIO.setmode(GPIO.BCM)

GPIO.setwarnings(False)

# 电机引脚初始化

for pin in [MOTOR_A_EN, MOTOR_A_IN1, MOTOR_A_IN2,

MOTOR_B_EN, MOTOR_B_IN3, MOTOR_B_IN4]:

GPIO.setup(pin, GPIO.OUT)

GPIO.output(pin, False)

# 超声波引脚

GPIO.setup(TRIG, GPIO.OUT)

GPIO.setup(ECHO, GPIO.IN)

# PWM调速

pwm_a = GPIO.PWM(MOTOR_A_EN, 100)

pwm_b = GPIO.PWM(MOTOR_B_EN, 100)

pwm_a.start(0)

pwm_b.start(0)

def motor_forward(speed=70):

GPIO.output(MOTOR_A_IN1, True)

GPIO.output(MOTOR_A_IN2, False)

GPIO.output(MOTOR_B_IN3, True)

GPIO.output(MOTOR_B_IN4, False)

pwm_a.ChangeDutyCycle(speed)

pwm_b.ChangeDutyCycle(speed)

def motor_backward(speed=70):

GPIO.output(MOTOR_A_IN1, False)

GPIO.output(MOTOR_A_IN2, True)

GPIO.output(MOTOR_B_IN3, False)

GPIO.output(MOTOR_B_IN4, True)

pwm_a.ChangeDutyCycle(speed)

pwm_b.ChangeDutyCycle(speed)

def motor_left(speed=70):

GPIO.output(MOTOR_A_IN1, False)

GPIO.output(MOTOR_A_IN2, True)

GPIO.output(MOTOR_B_IN3, True)

GPIO.output(MOTOR_B_IN4, False)

pwm_a.ChangeDutyCycle(speed)

pwm_b.ChangeDutyCycle(speed)

def motor_right(speed=70):

GPIO.output(MOTOR_A_IN1, True)

GPIO.output(MOTOR_A_IN2, False)

GPIO.output(MOTOR_B_IN3, False)

GPIO.output(MOTOR_B_IN4, True)

pwm_a.ChangeDutyCycle(speed)

pwm_b.ChangeDutyCycle(speed)

def motor_stop():

for pin in [MOTOR_A_IN1, MOTOR_A_IN2, MOTOR_B_IN3, MOTOR_B_IN4]:

GPIO.output(pin, False)

pwm_a.ChangeDutyCycle(0)

pwm_b.ChangeDutyCycle(0)

def measure_distance():

GPIO.output(TRIG, False)

time.sleep(0.05)

GPIO.output(TRIG, True)

time.sleep(0.00001)

GPIO.output(TRIG, False)

timeout = time.time()

while GPIO.input(ECHO) == 0:

if time.time() - timeout > 0.1:

return -1

pulse_start = time.time()

while GPIO.input(ECHO) == 1:

if time.time() - pulse_start > 0.1:

return -1

pulse_end = time.time()

return (pulse_end - pulse_start) * 34300 / 2

# 主循环——自动避障

try:

while True:

dist = measure_distance()

print(f"前方距离: {dist:.1f} cm")

if dist < 0:

time.sleep(0.1)

continue

if dist > SAFE_DISTANCE:

motor_forward(60)

else:

motor_stop()

time.sleep(0.3)

motor_backward(50)

time.sleep(0.5)

motor_stop()

# 随机左转

motor_left(60)

time.sleep(0.8)

time.sleep(0.1)

except KeyboardInterrupt:

motor_stop()

GPIO.cleanup()

```


@@IMG@@b19-8.jpg@@/IMG@@

六、扩展建议

增加红外传感器:检测左右两侧障碍,实现更智能的避障策略

添加摄像头:实现视觉导航和图像传输

增加编码器:实现精确里程计和定位

PWM调速优化:实现更平滑的加减速和转向

手机控制:安装Web服务器,通过手机浏览器控制小车


@@IMG@@b19-11.jpg@@/IMG@@

Web遥控界面示例:

通过Apache/Nginx搭建Web控制页面,在手机上即可远程操控,同时查看摄像头实时画面。

*本文整理自树莓派实验室(shumeipai.nxez.com)的相关教程*