基于 STM32 的工程级扫地机器人方案。这个方案摒弃了玩具级的"随机乱撞",引入了半结构化路径规划。
一、系统总体架构(分层设计)
| 层级 | 功能 | 核心技术 |
|---|---|---|
| 执行层 | 运动与清扫 | 直流电机、PID调速、PWM |
| 感知层 | 环境探测 | 超声波阵列、红外悬崖检测 |
| 决策层 | 避障行为 | 有限状态机 (FSM) |
| 规划层 | 清扫路径 | 弓字形覆盖、沿墙算法 |
二、硬件选型与接线(STM32 核心)
1. 核心控制器
- MCU:STM32F103RET6(或 F407,Flash 大,IO 多)
- 原因:需要处理多路超声波时序和 PID 运算。
2. 运动底盘
- 驱动方式 :差速驱动(左右轮独立电机 + 万向轮)。
- 电机:带编码器的直流减速电机(用于里程计和速度闭环)。
- 驱动:TB6612FNG 或 DRV8833。
3. 传感器阵列(避障核心)
- 前方避障:3 个 HC-SR04 超声波(左、中、右),覆盖 120°。
- 悬崖检测:2 个红外反射传感器(机身底部前方左右),防止跌落楼梯。
- 碰撞检测:1 个微动开关(保险丝)。
- 沿墙辅助:1 个侧面红外/超声波(用于贴边清扫)。
4. 清扫机构
- 主刷:滚刷电机(吸入垃圾)。
- 边刷:侧边电机(扫入墙角垃圾)。
三、核心控制算法
1. 超声波避障逻辑(防撞)
不要只看"小于 10cm 就停",那样太迟钝。建议采用三级预警:
c
// 伪代码:超声波数据处理
float distance_center = Get_Ultrasonic(CENTER);
float distance_left = Get_Ultrasonic(LEFT);
float distance_right = Get_Ultrasonic(RIGHT);
#define DANGER_DIST 15.0f // 厘米,危险距离
#define SAFE_DIST 30.0f
if (distance_center < DANGER_DIST) {
// 紧急停止并后退
Robot_Backward(500); // 后退500ms
// 随机转向,防止卡死
if (rand() % 2) Robot_TurnLeft(90);
else Robot_TurnRight(90);
} else if (distance_center < SAFE_DIST) {
// 减速并微调
Set_Speed(SLOW_SPEED);
// 如果左边空,向左转避开
if (distance_left > distance_right) {
Robot_TurnLeft(15);
} else {
Robot_TurnRight(15);
}
}
2. 有限状态机 (FSM) 行为控制
这是实现"智能"的关键。机器人永远处于某一种状态。
c
typedef enum {
STATE_IDLE, // 待机
STATE_CLEANING, // 清扫中(直行)
STATE_BACKING, // 后退
STATE_TURNING, // 转向
STATE_EDGE_CLEANING, // 沿墙清扫
STATE_STUCK // 被困(报警)
} Robot_State_t;
Robot_State_t robot_state = STATE_CLEANING;
void Robot_State_Machine(void) {
switch (robot_state) {
case STATE_CLEANING:
if (Is_Collision() || Is_Cliff()) {
robot_state = STATE_BACKING;
} else if (Is_Wall_On_Left()) {
robot_state = STATE_EDGE_CLEANING; // 切换到沿墙模式
} else {
Robot_Forward(NORMAL_SPEED);
}
break;
case STATE_EDGE_CLEANING:
// 沿墙算法:保持左侧距离恒定(如 5cm)
Wall_Following_Control();
break;
// ... 其他状态处理
}
}
3. 路径规划(从"乱撞"到"覆盖")
单纯的随机碰撞效率极低(覆盖率 < 60%)。
- 基础版(推荐) :弓字形规划 (Bow Pattern) 。
- 机器人沿着一条直线清扫,直到碰到墙。
- 碰到墙后,向右转 90°,前进一小段(换行距)。
- 再右转 90°,继续直线清扫。
- 进阶版 :结合编码器里程计,记录行走距离,实现真正的矩形覆盖。
四、STM32 程序框架(代码片段)
1. 电机 PID 闭环(保证走直线)
扫地机器人必须走直线,否则扫不干净。
c
// 编码器读取速度
int16_t speed_left = Read_Encoder(LEFT);
int16_t speed_right = Read_Encoder(RIGHT);
// 差速修正(简单P控制)
int16_t speed_error = speed_left - speed_right;
int16_t adjust = speed_error * 0.5; // P系数
Set_Motor_PWM(LEFT, target_speed + adjust);
Set_Motor_PWM(RIGHT, target_speed - adjust);
2. 定时器中断(控制节拍)
所有的决策必须在固定频率下执行,防止逻辑混乱。
c
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
if (htim->Instance == TIM2) { // 10ms 中断
// 1. 读取传感器
Sensor_Update();
// 2. 执行状态机
Robot_State_Machine();
// 3. 更新电机PID
Motor_PID_Update();
}
}
参考代码 实现智能控制,并进行超声波避障 www.youwenfan.com/contentcsu/69815.html
五、清扫有效性保障
- 边刷与风道:硬件设计上,边刷必须将灰尘扫入吸尘口,否则吸力再大也没用。
- 越障能力:轮子的直径要大于 4cm,才能越过门槛和地毯边缘。
- 防缠绕:主刷电机要有电流检测,如果电流过大(被电线缠住),立即反转或停止。
- 回充对接(进阶):在充电桩两侧放置红外信标,机器人通过寻找红外光源自动对接充电。
六、调试建议
- 先调底盘:在不装清扫机构的情况下,先让底盘能走直线、能精准转 90 度。
- 再调避障:用手挡住超声波,看机器人是否能及时减速和转向。
- 最后调路径:在一个空房间里测试,看是否出现明显的漏扫区域。