1、扫地机系统概述:从硬件到软件的完整拼图
做扫地机嵌入式开发这些年,我最大的感受就是——这玩意儿看着简单,实际上是个系统工程。你想想看,一个巴掌大的机器,要同时处理传感器数据、控制电机、管理电池、跑算法,还得保证实时性。嗯,今天我们就从硬件架构开始,一层层把这块拼图拼完整。
1.1 硬件架构:扫地机的"骨骼"与"感官"
先说说硬件。我习惯把扫地机的硬件分成四大块:大脑(MCU)、感官(传感器)、手脚(电机)、能量(电池)。这四块缺一不可,配合不好就容易出问题。
MCU选型:不是越强越好
MCU是核心,但选型有讲究。我个人习惯看三点:算力、外设资源、功耗。举个例子,我做过一个项目,一开始选了STM32F103,结果发现同时处理激光雷达数据和SLAM算法时,CPU占用率飙到90%以上。后来换了STM32F407,带FPU,浮点运算快了不少。
常见的MCU选型方案:
| 芯片型号 | 内核 | 主频 | 适用场景 |
|---|---|---|---|
| STM32F103 | Cortex-M3 | 72MHz | 基础扫地机(无SLAM) |
| STM32F407 | Cortex-M4 | 168MHz | 中端扫地机(带简单SLAM) |
| STM32H743 | Cortex-M7 | 480MHz | 高端扫地机(激光+视觉融合) |
| 国产GD32F450 | Cortex-M4 | 200MHz | 性价比方案 |
传感器:扫地机的"眼睛"和"耳朵"
传感器这块,种类多、接口杂。我整理了一下常见的:
- 激光雷达(LDS):UART接口,数据量较大,需要DMA接收。我遇到过数据丢包的问题,后来加了环形缓冲区才解决。
- 陀螺仪/加速度计(IMU):I2C或SPI接口,用于姿态估计。注意,IMU数据有温漂,需要做校准。
- 碰撞传感器:GPIO中断,简单但重要。我曾经因为没做消抖处理,导致机器在门槛处反复碰撞。
- 悬崖传感器:红外或超声波,ADC采样。这里有个坑——不同地面反射率不同,阈值要动态调整。
- 里程计(轮速计):编码器输入,用于定位。精度取决于编码器线数和轮径校准。
电机与驱动:动力系统的"肌肉"
电机一般用直流有刷电机或无刷电机。驱动方式有两种:
- H桥驱动:用PWM控制方向和速度。注意死区时间设置,否则容易烧MOS管。
- 专用驱动芯片:比如DRV8833,集成度高,但要注意散热。
我习惯在电机驱动上加电流采样,用来做堵转检测和负载判断。你想想看,如果机器卡在地毯边缘,电机电流会突然增大,这时候及时停止能避免烧电机。
电池管理:续航的"心脏"
电池这块,锂电池是主流。需要关注三点:
- 电量检测:用ADC采样电池电压,但要注意——电池放电曲线不是线性的。我做过一个简单的查表法,精度在5%以内,够用了。
- 充电管理:用专用芯片如TP4056,注意充电电流不要超过电池规格。
- 低电量保护:电压低于阈值时,强制回充。我曾经因为阈值设得太低,导致电池过放,直接报废了一块电池。
1.2 软件架构分层:把复杂问题拆解
硬件搭好了,软件怎么组织?我推荐分层架构。说白了,就是把代码按职责拆开,每层只管自己的事。这样好处很明显:好维护、好测试、好移植。
我常用的分层方式:
| 层级 | 职责 | 典型模块 |
|---|---|---|
| 应用层 | 业务逻辑、决策 | 路径规划、避障策略、回充逻辑 |
| 中间件层 | 算法封装、数据融合 | SLAM、卡尔曼滤波、PID控制 |
| 驱动层 | 硬件抽象、寄存器操作 | GPIO、UART、I2C、PWM驱动 |
举个例子,驱动层只负责"读传感器数据"和"写电机PWM"。中间件层拿到数据后做滤波和融合。应用层只管"前方有障碍物,左转"。这样每层改动不影响其他层。
1.3 实时操作系统选型:FreeRTOS vs RT-Thread
要不要上RTOS?我的答案是:必须上。扫地机有多个并发任务——传感器采集、电机控制、算法运算、通信处理。用裸机轮询,你想想看,一个传感器采集卡住了,整个系统就瘫痪了。
选哪个?我两个都用过,说说感受。
FreeRTOS:轻量、稳定、生态好
- 优点:代码量小,RAM占用低,适合资源受限的MCU。文档齐全,网上资料多。
- 缺点:功能相对基础,没有设备框架,需要自己封装驱动。
- 适用场景:RAM小于64KB、Flash小于256KB的MCU。
RT-Thread:功能丰富、组件化
- 优点:有设备驱动框架、文件系统、网络协议栈,开箱即用。支持动态加载模块。
- 缺点:代码量大,对RAM要求高。学习曲线稍陡。
- 适用场景:RAM大于128KB、需要复杂功能的中高端MCU。
我个人习惯:小项目用FreeRTOS,大项目用RT-Thread。举个例子,一个只有激光雷达和基础避障的扫地机,FreeRTOS完全够用。但如果要加视觉识别、语音控制、OTA升级,RT-Thread的组件生态能省不少事。
任务划分示例(FreeRTOS)
我一般这样划分任务:
// 任务优先级定义
#define TASK_SENSOR_PRIO 3 // 传感器采集,最高优先级
#define TASK_MOTOR_PRIO 2 // 电机控制
#define TASK_ALGO_PRIO 1 // 算法运算
#define TASK_COMM_PRIO 0 // 通信处理,最低优先级
// 任务创建
xTaskCreate(sensor_task, "Sensor", 256, NULL, TASK_SENSOR_PRIO, NULL);
xTaskCreate(motor_task, "Motor", 128, NULL, TASK_MOTOR_PRIO, NULL);
xTaskCreate(algo_task, "Algo", 512, NULL, TASK_ALGO_PRIO, NULL);
xTaskCreate(comm_task, "Comm", 256, NULL, TASK_COMM_PRIO, NULL);
注意看,传感器任务优先级最高,因为数据要实时采集。算法任务栈空间最大,因为SLAM运算需要大量局部变量。通信任务优先级最低,丢几条日志无所谓。
小结
好了,这一章我们聊了扫地机的硬件架构、软件分层和RTOS选型。说白了,就是搞清楚"用什么芯片、怎么组织代码、用什么系统"。下一章我们会深入驱动层,讲讲具体怎么写传感器驱动和电机控制。嗯,到时候我会分享一些实际项目中的踩坑经验,敬请期待。