1. 项目概述
这个项目让我想起了十年前第一次参加大学生电子设计竞赛时的场景。当时我们团队花了整整三个月时间,就为了捣鼓出一辆能自动沿着黑线跑的小车。如今看来,这种基于单片机的寻迹巡线避障智能小车,依然是嵌入式系统入门的绝佳练手项目。
简单来说,这个系统就是让小车能够自主完成三个核心功能:通过地面上的引导线自动行驶(寻迹巡线)、实时检测前方障碍物(避障)、并根据环境情况做出合理的运动决策(智能控制)。别看它体积小,却涵盖了传感器技术、电机控制、算法设计等多个嵌入式开发的关键领域。
2. 系统整体设计
2.1 硬件架构设计
硬件部分我习惯从功能模块来划分:
- 主控模块:STC89C52RC单片机(性价比之王,新手友好)
- 传感模块:
- 5路红外对管组成的寻迹阵列(TCRT5000)
- 超声波模块HC-SR04负责前方障碍检测
- 执行模块:
- L298N电机驱动板
- 两个直流减速电机(配编码器更好)
- 电源模块:
- 18650锂电池组(7.4V)
- AMS1117稳压芯片(5V和3.3V输出)
特别提醒:电机一定要单独供电!我吃过亏,用同一组电源给单片机和电机供电,电机启动时的电流波动会导致单片机复位。
2.2 软件流程设计
软件架构采用经典的前后台系统:
c复制void main() {
hardware_init(); // 硬件初始化
while(1) {
track_detect(); // 巡线检测
obstacle_check(); // 障碍检测
motor_control(); // 电机控制
delay_ms(10); // 适当延时
}
}
3. 核心功能实现细节
3.1 寻迹巡线实现
寻迹的核心在于红外对管的布局和阈值调整。我推荐这种排列方式:
code复制[左2] [左1] [中] [右1] [右2]
对应的检测逻辑:
c复制void track_detect() {
int sensor[5];
// 读取传感器状态
for(int i=0; i<5; i++) {
sensor[i] = digitalRead(PIN_SENSOR[i]);
}
// 决策逻辑
if(sensor[2]==0) { // 中间传感器检测到黑线
go_straight();
} else if(sensor[1]==0) {
turn_left(30); // 轻度左转
} else if(sensor[3]==0) {
turn_right(30); // 轻度右转
}
// 更复杂的判断可以继续扩展
}
3.2 超声波避障实现
超声波测距要注意温度补偿(虽然HC-SR04精度要求不高):
c复制float get_distance() {
trig = 1;
delay_us(10);
trig = 0;
while(!echo); // 等待回波
long start = micros();
while(echo); // 等待回波结束
long duration = micros() - start;
// 声速常温下约343m/s,计算距离(cm)
return duration * 0.0343 / 2;
}
实测技巧:超声波模块最好倾斜15度安装,可以减少地面反射干扰。我在实验室地板上测试时,平放模块经常误报障碍。
4. 电机控制策略
4.1 PWM调速实现
L298N的使能端接PWM可以实现调速:
c复制void set_motor_speed(int left, int right) {
// 限制PWM范围
left = constrain(left, 0, 255);
right = constrain(right, 0, 255);
analogWrite(PIN_PWM_LEFT, left);
analogWrite(PIN_PWM_RIGHT, right);
}
4.2 运动控制算法
我总结了几种常见巡线算法效果对比:
| 算法类型 | 响应速度 | 稳定性 | 实现难度 | 适用场景 |
|---|---|---|---|---|
| 简单阈值 | 快 | 差 | 易 | 直线赛道 |
| PID控制 | 中 | 优 | 中 | 弯道多 |
| 模糊控制 | 慢 | 优 | 难 | 复杂路径 |
新手建议从PD控制开始:
c复制// 简易PD控制器
int pd_control(int error) {
static int last_error = 0;
int output = Kp*error + Kd*(error - last_error);
last_error = error;
return output;
}
5. 系统调试与优化
5.1 传感器校准
红外对管需要现场校准:
- 将小车放在白色背景上,测量每个传感器的ADC值(White_Value)
- 放在黑线上测量(Black_Value)
- 阈值 = (White_Value + Black_Value)/2
5.2 常见问题排查
我遇到过的典型问题及解决方案:
| 现象 | 可能原因 | 解决方法 |
|---|---|---|
| 小车左右摇摆 | PD参数过大 | 减小Kd值 |
| 冲出赛道 | 传感器间距过大 | 调整传感器间距至1-1.5cm |
| 超声波误报 | 电源干扰 | 加装100uF电容 |
| 电机转速不均 | PWM频率不适配 | 调整频率至1-3kHz |
6. 进阶改进方向
如果基础功能已经实现,可以尝试:
- 增加蓝牙遥控功能(HC-05模块)
- 添加OLED显示屏实时显示传感器数据
- 改用PID算法提高巡线精度
- 增加赛道记忆功能
我在第二代小车上增加了MPU6050陀螺仪,实现了更精准的弯道控制。数据显示,加入角度反馈后,90度直角弯的通过率从72%提升到了89%。
最后分享一个布线心得:信号线最好用双绞线,电源线要足够粗(至少AWG22)。曾经因为线材选择不当,导致超声波模块间歇性失灵,排查了整整两天才发现是电源线阻抗过大。