这个基于STM32的智能防丢器设计,是我在去年为一个户外运动爱好者社群开发的实用型设备。它整合了卫星定位、无线通信、声光报警和避障检测四大核心功能模块,解决了钥匙、背包等小件物品在户外场景中容易丢失的痛点。
整个系统的硬件架构围绕STM32F103C8T6这颗性价比极高的Cortex-M3内核MCU搭建。选择这款芯片主要基于三点考量:首先是72MHz主频足够处理GPS数据解析和无线通信任务;其次是内置的64KB Flash和20KB SRAM满足程序存储和运行需求;最重要的是其丰富的外设接口(3个USART、2个SPI、2个I2C)完美适配本项目所有外设的连接需求。
系统工作时,定位模块(支持北斗/GPS双模)实时获取经纬度数据,通过WIFI模块上传至手机APP。当触发防丢模式时,设备会启动高亮LED闪烁和蜂鸣器报警,配合APP地图定位,形成"远程定位+近场声光"的双重寻找方案。新增的红外避障模块则扩展了安全预警功能,当检测到障碍物时会触发蜂鸣器报警,这个功能在夜间或能见度低的环境中特别实用。
STM32F103C8T6最小系统板作为控制核心,通过以下引脚分配连接各模块:
1.44寸TFT彩屏选用ST7735S驱动芯片的型号,其128x128分辨率足够显示定位信息。实际调试中发现,在户外强光下需要将屏幕背光调到最大才能清晰显示,因此我们在硬件上增加了背光驱动电路,使用MOS管IRLML6244配合PWM调光,既保证亮度又兼顾功耗。
定位模块选用ATGM336H,这款国产模块的优势在于:
WIFI通信使用ESP-01S模块,通过AT指令与STM32交互。在软件层我们实现了以下通信协议:
c复制// 数据帧格式示例
typedef struct {
uint8_t head; // 0xAA
float latitude; // 纬度
float longitude; // 经度
uint8_t alert; // 报警状态
uint8_t checksum; // 校验和
} WiFi_Frame;
电源管理采用TP4056锂电池充电芯片+AMS1117-3.3V稳压的方案,支持USB充电和3.7V锂电供电。实测待机电流约25mA,报警模式峰值电流可达150mA(LED全亮时)。
声光报警电路有两个关键设计点:
红外避障模块选用E18-D80NK,这款光电传感器的优势是:
系统软件采用前后台架构,主循环中处理显示更新和状态检测,中断服务程序处理串口通信。关键任务调度如下:
flow复制st=>start: 系统初始化
op1=>operation: GPS数据解析
op2=>operation: WIFI数据传输
op3=>operation: 屏幕刷新
op4=>operation: 按键扫描
op5=>operation: 避障检测
e=>end: 低功耗模式
st->op1->op2->op3->op4->op5->e
GPS数据解析采用状态机实现,以下是对$GPRMC语句的解析流程:
c复制void GPS_Parse(char *buf) {
char *p = strtok(buf, ",");
int field = 0;
while(p != NULL) {
switch(field++) {
case 1: // UTC时间
sscanf(p, "%2hhd%2hhd%2hhd", &hour, &min, &sec);
break;
case 3: // 纬度
latitude = atof(p);
break;
// ...其他字段解析
}
p = strtok(NULL, ",");
}
}
在实际测试中,我们发现GPS信号在城区容易出现漂移问题,为此实现了两种滤波算法:
c复制float moving_avg(float new_val) {
static float buffer[5] = {0};
static uint8_t index = 0;
buffer[index++] = new_val;
if(index >= 5) index = 0;
float sum = 0;
for(int i=0; i<5; i++) {
sum += buffer[i];
}
return sum / 5;
}
c复制typedef struct {
float q; // 过程噪声协方差
float r; // 观测噪声协方差
float x; // 估计值
float p; // 估计误差协方差
float k; // 卡尔曼增益
} Kalman_Filter;
float kalman_update(Kalman_Filter *kf, float measurement) {
// 预测
kf->p = kf->p + kf->q;
// 更新
kf->k = kf->p / (kf->p + kf->r);
kf->x = kf->x + kf->k * (measurement - kf->x);
kf->p = (1 - kf->k) * kf->p;
return kf->x;
}
APP与设备间的通信采用自定义的二进制协议,比JSON等文本协议更节省带宽。关键设计要点:
code复制0 1 2-5 6-9 10 11
+------+------+-------+-------+------+------+
| 0xAA | 0x01 | 纬度 | 经度 | 状态 | 校验 |
+------+------+-------+-------+------+------+
c复制uint8_t calc_checksum(uint8_t *data, uint8_t len) {
uint8_t sum = 0;
for(int i=0; i<len-1; i++) {
sum ^= data[i]; // 异或校验
}
return sum;
}
我们在三种典型环境下进行了定位测试(静态条件下持续5分钟):
| 环境 | 水平误差(m) | 冷启动时间(s) | 数据更新率(Hz) |
|---|---|---|---|
| 开阔广场 | 2.5 | 38 | 1.0 |
| 城市街道 | 8.7 | 72 | 0.6 |
| 室内窗边 | 15.3 | 120 | 0.2 |
测试发现两个关键问题:
解决方案:
通过测量各模块的工作电流,我们发现三个耗电大户:
采取的优化策略:
实测优化后的电池续航:
| 工作模式 | 平均电流 | 2000mAh电池续航 |
|---|---|---|
| 持续定位 | 65mA | 30小时 |
| 间歇工作 | 28mA | 71小时 |
| 深度睡眠 | 1.5mA | 55天 |
E18-D80NK模块需要根据使用环境进行灵敏度校准,具体步骤:
常见问题处理:
推荐使用3D打印制作防水外壳,注意:
我们最终采用的方案:
在多次户外实测中,这个防丢器最远在1.5公里外成功触发定位找回。一个意外的收获是,红外避障功能在夜间徒步时还能起到前方障碍预警的作用。如果要做商业级产品,下一步我会重点优化电源管理系统,并考虑通过FCC/CE认证的相关设计要求。