1. 项目概述
这个项目是我去年参加电子设计竞赛时的实战作品,一个基于单片机的智能灭火避障小车。它不仅能够自主导航避开障碍物,还能通过火焰传感器检测火源并自动前往灭火。整个系统从硬件选型到算法设计都是我们自己完成的,期间踩了不少坑,也积累了很多宝贵的经验。
这种智能小车在消防演练、危险环境作业等场景都有实际应用价值。相比市面上动辄上万的商用消防机器人,我们的方案成本控制在500元以内,但实现了80%以上的核心功能。下面我就从设计思路到具体实现,把整个项目的技术细节和实操经验完整分享给大家。
2. 核心功能设计
2.1 系统架构设计
整个系统采用模块化设计思路,主要包含以下几个核心模块:
- 主控模块:选用STM32F103C8T6作为主控芯片,性价比高且资源充足
- 驱动模块:L298N电机驱动板配合直流减速电机
- 传感模块:
- 火焰传感器(5个方向布置)
- 超声波避障传感器(HC-SR04)
- 红外循迹模块(可选)
- 执行机构:小型水泵+储水罐组成的灭火装置
- 电源管理:12V锂电池组配合7805稳压模块
这种架构设计最大的优势是各模块相对独立,调试时可以分模块进行,降低了整体开发难度。在实际组装时,我们采用了分层布局的方式:底层是电机和轮子,中间层是主控板和传感器,上层是灭火装置。
2.2 关键算法设计
2.2.1 避障算法
我们采用了改进的势场法避障算法。与传统的超声波避障不同,我们引入了动态权重机制:
c复制// 伪代码示例
float obstacle_avoidance() {
float left_dist = get_ultrasonic(LEFT);
float right_dist = get_ultrasonic(RIGHT);
float front_dist = get_ultrasonic(FRONT);
// 动态权重计算
float k = 1.0 - (front_dist / MAX_DIST);
float turn_direction = (right_dist - left_dist) * k;
return constrain(turn_direction, -1.0, 1.0);
}
这个算法的特点是:当前方障碍物较远时,转向幅度较小;当障碍物接近时,转向会变得更加激进。实测下来,这种算法能让小车在复杂环境中的避障成功率提升约30%。
2.2.2 火源定位算法
火焰检测采用了多传感器数据融合的方式。我们在小车四周布置了5个火焰传感器(前、左前、右前、左、右),通过比较各传感器的读数来确定火源方向:
code复制传感器布局:
[左前] [前] [右前]
[左] [右]
火源定位的核心逻辑是:
- 持续扫描所有传感器读数
- 当任一传感器值超过阈值时,进入火源追踪模式
- 根据各传感器读数差计算转向角度
- 当所有前向传感器读数均衡且达到最大时,判定为对准火源
3. 硬件实现细节
3.1 关键元器件选型
经过多次对比测试,我们最终确定的元器件清单如下:
| 元器件 | 型号 | 参数 | 单价 | 选择理由 |
|---|---|---|---|---|
| 主控芯片 | STM32F103C8T6 | ARM Cortex-M3, 72MHz | 15元 | 性价比高,资源充足 |
| 电机驱动 | L298N | 2A峰值电流 | 12元 | 驱动能力强,稳定性好 |
| 直流电机 | JGA25-370 | 6V 100RPM | 25元/个 | 扭力适中,速度可控 |
| 超声波 | HC-SR04 | 2cm-400cm | 8元 | 精度满足需求 |
| 火焰传感器 | 5路模拟 | 0-1024 | 5元/个 | 灵敏度可调 |
特别提醒:电机选型时要注意转速和扭矩的平衡。我们最初选了300RPM的电机,结果发现速度太快导致控制困难,后来换成100RPM的才达到理想效果。
3.2 PCB设计与布线技巧
为了减少干扰和提高可靠性,我们自主设计了双层PCB板。几个关键经验:
- 电源走线:主电源线宽不小于1.5mm,数字地和模拟地分开最后单点连接
- 信号隔离:电机驱动信号与其他信号线保持距离,必要时加磁珠隔离
- 去耦电容:每个IC的电源引脚就近放置0.1uF陶瓷电容
- 传感器接口:所有传感器接口都加了TVS二极管保护
实际布线时,我们采用了"星型"供电布局,从电源管理芯片引出多路独立供电,有效解决了早期版本中电机干扰传感器的问题。
4. 软件实现详解
4.1 主控制流程
整个系统的软件采用状态机架构,主要状态包括:
- 待机状态:系统初始化,等待启动信号
- 巡逻状态:随机移动+避障
- 火警状态:检测到火源后进入灭火流程
- 灭火状态:对准火源并启动水泵
- 返回状态:灭火完成后返回起点
状态转换图如下(用文字描述):
待机 -> (启动信号) -> 巡逻
巡逻 -> (检测到火焰) -> 火警
火警 -> (对准火源) -> 灭火
灭火 -> (火焰消失) -> 返回
返回 -> (到达起点) -> 巡逻
4.2 关键代码实现
4.2.1 电机控制
我们采用了PWM调速配合PID控制算法:
c复制// PID控制器实现
typedef struct {
float Kp, Ki, Kd;
float integral;
float prev_error;
} PIDController;
float pid_update(PIDController* pid, float error, float dt) {
float derivative = (error - pid->prev_error) / dt;
pid->integral += error * dt;
pid->prev_error = error;
return pid->Kp * error + pid->Ki * pid->integral + pid->Kd * derivative;
}
// 电机控制示例
void motor_control(float speed_left, float speed_right) {
static PIDController pid_left, pid_right;
float error_left = speed_left - get_motor_speed(LEFT);
float error_right = speed_right - get_motor_speed(RIGHT);
float output_left = pid_update(&pid_left, error_left, 0.01);
float output_right = pid_update(&pid_right, error_right, 0.01);
set_motor_pwm(LEFT, output_left);
set_motor_pwm(RIGHT, output_right);
}
4.2.2 传感器数据处理
为了提高传感器数据的可靠性,我们采用了滑动窗口滤波算法:
c复制#define WINDOW_SIZE 5
float sliding_window_filter(float new_value) {
static float window[WINDOW_SIZE] = {0};
static uint8_t index = 0;
window[index] = new_value;
index = (index + 1) % WINDOW_SIZE;
float sum = 0;
for(int i=0; i<WINDOW_SIZE; i++) {
sum += window[i];
}
return sum / WINDOW_SIZE;
}
5. 调试与优化经验
5.1 常见问题排查
在实际调试过程中,我们遇到了不少典型问题,这里总结几个最有代表性的:
-
电机干扰传感器:
- 现象:电机启动时超声波读数跳动
- 解决方案:加强电源滤波,传感器信号线使用屏蔽线
-
火焰误检测:
- 现象:日光灯下误触发
- 解决方案:调整传感器阈值,增加红外滤波片
-
水泵压力不足:
- 现象:射程不够
- 解决方案:改用隔膜泵,增加储水罐气压
5.2 性能优化技巧
经过多次迭代,我们总结出几个关键优化点:
-
传感器采样优化:
- 超声波传感器采用交错采样,避免相互干扰
- 火焰传感器采用分时复用ADC,节省资源
-
运动控制优化:
- 加入运动预测算法,减少急停急转
- 根据电池电压动态调整PWM占空比
-
功耗优化:
- 空闲时降低主频
- 非必要传感器周期性休眠
6. 扩展与改进方向
虽然基础功能已经实现,但这个项目还有不少可以提升的空间:
- 增加视觉识别:替换火焰传感器为摄像头+OpenMV,提高火源识别精度
- 多机协作:通过无线模块实现多车协同灭火
- 路径规划:加入SLAM算法,实现地图构建和最优路径规划
- 远程监控:添加WiFi模块,支持手机APP监控
在实际测试中,我们发现最需要改进的是火源定位精度。目前的方案在强光环境下表现不够理想,下一步计划改用热成像传感器来提高可靠性。
