资讯动态

基于STM32的防跌倒定位手环设计:从传感器融合到告警联动

发布时间:2026/10/21 9:03:56 来源:尧图企业网站定制
这标题一眼扫过去STM32、跌倒、GSM、GPS北斗、APP地图、手电筒全堆在一起看着像要把半个物联网塞进一个手环里。跟你说句实话我头一回拿到类似题目时也觉得慌但真拆开做下来会发现每个模块单独拎出来都是很成熟的东西真正的难点不在单个功能而在怎么把传感器、通信、定位和电源顺畅地串成一个能用的整体。这篇就按我实际做下来的顺序从方案选型、跌倒检测算法到短信告警、APP标点和按键手电筒电路一层层讲清楚中间会穿插不少只有动手调才会踩到的坑。这个项目本质上是一个带紧急呼救功能的老人防跌倒定位手环适合正在做嵌入式课程设计、物联网小项目或者电子竞赛题目的朋友参考也适合想入门STM32加传感器组合开发的人拿来练手。哪怕你不做一模一样的硬件里面关于串口资源分配、低功耗设计、模块联调和误报排查的思路放到其他智能穿戴项目里一样能用。1. 先拆标题四个子系统各有各的活儿1.1 系统组成与数据流向先别被项目编号里的数字唬住26-036这种更像归档编号或题目序号真正要关心的是功能。整个系统可以分成四条线感知线MPU6050六轴传感器负责采集加速度和角速度跌倒判定在主控里做。定位与告警线GPS北斗双模模块输出经纬度GSM模块把预置短信发给家人。交互线蓝牙模块把坐标和状态发给手机APPAPP负责弹窗告警并在地图上标点。辅助输出线按键控制高亮LED也就是手电筒功能。数据流是这么走的传感器持续检测人体运动状态一旦算法判定跌倒主控立刻读取最近一次有效定位同时做两件事——通过GSM发短信通过蓝牙把经纬度帧传给APP。短信是兜底方案因为老人不一定随身带着手机家人的手机却一定收得到消息APP是增强体验能直接在地图上看到位置。1.2 为什么主控选STM32而不是其他片子STM32F103C8T6这颗料是这个项目里很常见的选型Cortex-M3内核72MHz主频64KB Flash、20KB RAM够跑跌倒算法和协议解析。更重要的是外设接口数量GPS、GSM、蓝牙三个模块各占一路串口MPU6050走I2C按键占GPIOLED用定时器的PWM通道这些资源一颗F103刚好全部够用不用升到F4系列。有朋友问为什么不用ESP32毕竟它自带蓝牙和WiFi省一个模块。我个人的考虑是手环这类电池供电场景对休眠功耗很敏感ESP32的WiFi射频部分哪怕不联网功耗也明显高于蓝牙透传方案而且很多ESP32开发板的电压调理电路并不适合直接怼GSM这种瞬间大电流负载。STM32的资源不算豪华但每一路外设都能稳定工作生态和参考代码也足够多出了问题好查。2. 硬件选型与电路设计要点2.1 核心模块清单与替代方案我列一份自己用着顺手的清单后面调试时基本没在这些选型上返工模块接口作用我自己用过的替代选项STM32F103C8T6-主控国产同引脚兼容型号MPU6050I2C跌倒检测MPU6500、甚至单独加速度计GPS北斗双模模块UART经纬度定位单GPS模块但弱信号下不如双模GSM模块UART发送短信不同版本的4频GSM模块蓝牙从机模块UART透传坐标给APP低功耗蓝牙从机模块N沟道MOS管加高亮LEDGPIOPWM手电筒三极管方案但压降大选GPS北斗双模而不用单GPS是因为老人跌倒可能发生在楼群、树荫这种遮挡环境双模能多收一路卫星信号搜星数量和定位成功率明显好一些。GSM模块选成熟稳定的四频方案短信功能本质就是AT指令控制没必要追新。2.2 供电树与电源抗干扰这个项目的供电是必须先想清楚的因为GSM模块是典型的“电老虎”。它发送短信时瞬时电流能到1.5A到2A如果跟主控共用同一个稳压器电压一跌轻则短信发不出去重则STM32直接复位。我踩过这个坑之后把电源分成三路锂电池直接给GSM模块供电电池电压3.7V满电4.2V在模块上限内模块旁边要放1000uF以上电解电容和TVS管吸收尖峰。锂电池再经过低压差稳压器降到3.3V给STM32、传感器、蓝牙供电注意选静态电流小的稳压器否则待机功耗会很难看。高亮LED不经过主控电源直接由电池经过MOS管驱动避免LED大电流在主控板上产生地弹。地线处理上GSM模块的电源地、LED驱动地和主控数字地要尽量单点汇合否则GSM发射脉冲会通过地线干扰传感器跌倒检测数据里出现一堆毛刺那就麻烦了。2.3 按键手电筒的驱动细节手电筒功能看起来简单就是把LED点亮但直接拿GPIO怼LED的做法我劝你放弃。高亮LED正常工作电流从几十毫安到三百毫安以上GPIO根本提供不了时间一长还可能把IO烧掉。我用的方案是低压逻辑电平N沟道MOS管做低边驱动LED正极接电池正极负极接MOS管漏极源极接地栅极通过10k电阻下拉、再串一个限流电阻接STM32的GPIO。GPIO输出高电平时MOS管导通LED点亮。按键逻辑上做了短按和长按两种短按开关灯长按在低中高三档亮度之间切换。亮度调节用定时器PWM实现PWM频率我设在10kHz以上这个频率下听不到啸叫LED亮度变化也足够线性。软件里还要加一个互斥逻辑GSM发短信的瞬间不切换LED状态避免两者电流叠加把电池电压拖垮。3. 跌倒检测算法从传感器数据到“别乱报警”3.1 六轴数据到底在看什么MPU6050输出的六个数据里加速度计测的是“比力”也就是传感器受到的除重力外的合力静止时三轴合成值约等于1g这是判断姿态的基础陀螺仪测角速度积分能得角度但纯积分会漂移。手环场景里一般不搞太复杂的姿态解算而是抓住跌倒过程中几个肉眼可见的特征。我习惯先把合加速度幅值算出来每一步都把三轴加速度合成一个数a sqrt(x² y² z²)静止站着时这个值在1g附近正常走路时小幅度波动而跌倒过程里会先出现一个短暂失重段值掉到0.5g以下紧接着撞击地面瞬间冲到2.5g甚至3.5g以上。光看这个波形就够初步识别了。3.2 判定逻辑从冲击峰到姿态确认只靠合加速度峰值阈值误报会多到没法用。我一开始把阈值调到3g结果拍桌子、甩手、弯腰捡东西一样触发。后来把算法改成三段式判断效果才正常前置失重检测合加速度低于0.6g并持续几十毫秒说明身体正在快速向下移动。冲击峰检测失重后300毫秒内出现大于3.2g的尖峰说明发生了碰撞。姿态和静止确认冲击峰之后取两秒窗口计算人体倾角相对跌倒前基线的变化同时看这段窗口里加速度方差。倾角变化大于50度且方差很小说明人已经躺平不动这时才确认跌倒。核心伪代码长这样float smv sqrtf(ax*ax ay*ay az*az); if (smv 0.6f) { pre_fall true; } if (pre_fall smv 3.2f) { impact_time get_tick(); pre_fall false; } if (get_tick() - impact_time 2000 impact_time 0) { float tilt calc_tilt_angle(ax, ay, az); float variance calc_acc_var(window); if (tilt 50 variance 0.02f) { fall_confirmed true; } }这里最关键的是把倾角判断和静止判断加进去。弯腰捡东西虽然也有头部或躯干下移但结束后会恢复站立姿态不会出现“倾角持续大于50度还一动不动”的状态。剧烈运动虽然峰值高但后续加速度方差也会大于阈值不会误判成躺平。3.3 调阈值和实测心得算法写完了真正花时间的是调阈值。我的做法是准备一个能长时间记录数据的函数通过蓝牙把每帧的加速值、倾斜角、判断中间变量实时发到手机日志里然后做两类实验一类是模拟跌倒包括向前倒、向后倒、侧倒一类是干扰动作包括快走、跑步、跳起、蹲下、挥手、拍手。把数据画出来就能看到两类动作在“峰值高度”和“跌倒后稳定段”上的距离阈值取中间偏保守的位置。多找几个人测也很重要不同身高体重的人跌倒冲击曲线有差别年轻人模拟摔倒和老人真实摔倒的幅度也会不同。如果给老人用宁可灵敏度高一点让系统把某些剧烈动作当疑似跌倒触发告警也不能漏掉真正的跌倒家人被误报打扰几次比真正出事时没收到短信好得多。产品描述里也要写清楚这是辅助告警设备不能替代监护。4. 定位、短信告警与APP地图联动4.1 GPS北斗数据解析与坐标转换定位模块上电后会持续通过串口输出NMEA 0183协议文本一条典型的位置语句长这样$GNGGA,103530.00,3123.4567,N,12123.4567,E,1,08,1.2,12.3,M,-5.3,M,,*5F我一般从GGA语句里取经纬度和定位状态。GGA的第2字段是纬度格式是“度分”混合3123.4567代表31度23.4567分要先转换成十进制度才能给APP或短信用。转换代码很直接def conver_nmea_degree(value): # 3123.4567 - 31 23.4567 / 60 31.390945 integer_part int(value / 100) minute_part value - integer_part * 100 return integer_part minute_part / 60.0收到一条完整帧后先判断有没有“有效定位”标志如果定位无效就不要用这个坐标发短信。GPS在室内基本是无解的这也是整个系统里最需要容错的地方。我的处理办法是主控里常驻一个“最近一次有效坐标”每次解析到有效定位就更新跌倒发生时GPS还没有搜到星就用这个旧坐标短信内容里加一句“位置可能不准确”至少给家人一个大致方向。4.2 GSM短信发送的AT指令流程GSM模块用串口AT指令控制发短信是固定的套路发送: ATCMGF1\r\n // 切到文本模式回OK 发送: ATCMGS13812345678\r\n // 带双引号的接收号码 等待: 发送: 短信内容 发送: 0x1A // 十六进制0x1A代表CtrlZ告诉模块结束输入 等待: CMGS: 序号\r\nOK这里面最容易出问题的有三个地方第一ATCMGS后面必须是“回车换行”第二短信内容发出后不能随便加回车第三0x1A要用十六进制字节发而不是发字符“1A”。我调试时卡了半个多小时就是因为把0x1A当成两个ASCII字符发出去模块一直没反应。短信内容我建议设计成类似这样【跌倒告警】检测到XXX可能于10:30跌倒。 位置纬度31.390945经度121.234567。 若并非本人操作请尽快回拨确认。实测发一条短信从模块上电到发送成功大概需要十秒左右其中很大一部分时间花在网络注册和信号搜索上。GSM模块上电到能注册网络快则一两秒慢则十几秒程序里不能一上电就立刻发短信要先查询网络注册状态。4.3 蓝牙透传与APP地图标点蓝牙模块工作在透明传输模式主控往串口写什么手机APP就收到什么。我自定义了一个极简帧格式方便APP解析也方便我用调试助手验证$FALL,31.390945,121.234567,20240101103000*$FALL是帧类型后面是纬度、经度、时间戳星号做结尾。加一个帧头帧尾比裸发坐标可靠得多解析时遇到不完整帧直接丢弃不会把两帧数据拼错。APP端我用的方案是接入常见地图应用提供的开发者SDK流程大体一致申请开发者密钥、在工程配置文件里声明权限、初始化地图控件然后把经纬度做成地图上一个标记点再通过地址反查显示大致位置操作上不如专业地图App内置的“位置分享”方便但在自己产品里嵌入是合理的路径。拿到经纬度后先把地图移动到对应坐标并添加Marker再弹一个AlertDialog提示“检测到跌倒请确认”用户点按即可查看位置。如果没有条件完整开发APP也可以用手机上的蓝牙串口调试助手替代手环发送的原始帧能直接显示出来把经纬度复制到任意地图App里搜索一样能验证从定位到传输的整条链路。缺点是体验差但用来做功能验证足够了。5. 系统联调与低功耗优化5.1 联调顺序先模块后整机这类多模块项目最容易翻车的地方就是一步到位。所有模块连在一起才发现GPS串口和蓝牙串口接反了或者GSM上电瞬间把传感器数据冲乱排查起来非常痛苦。我的联调顺序固定为拿到最小系统板先点亮LED、跑通按键中断确认主控基本功能。分别接GPS、蓝牙、GSM三个模块用串口调试助手观察各自的输出确保每个模块都能独立工作。把跌倒检测算法单独跑起来用串口把中间变量打印出来拿着手环做各种夸张动作看波形。最后再组合触发跌倒后先看串口日志里有没有坐标再看短信有没有到手机最后看APP地图有没有标点。每一步都留下日志这样出问题能直接定位到具体环节而不是在一个大黑盒里瞎猜。5.2 功耗分析与续航估算戴在手腕上的设备功耗是绕不开的问题。手环平时处于检测状态传感器一直采数据是很费电的但MPU6050自带运动中断功能可以让它只在检测到明显加速度变化时才唤醒主控平时主控进入休眠模式。这样能明显压住静态功耗。GPS模块是最耗电的设备之一我把它设计成只在确认跌倒之后才启动宁可让家人多等几十秒定位也不让它一直开着烧电。GSM模块平时也让它休眠或者断电只有需要发短信时才唤醒。蓝牙模块可以在不传输时断开连接。按这个思路如果选用1000mAh锂电池理想情况下待机电流能压到1毫安到2毫安理论待机一个月左右实际使用中因为有蓝牙常连和频繁唤醒做不到那么长但比所有模块全开撑一天的情况好太多。功耗优化的坑也很典型某次我发现待机电流莫名其妙多了好几毫安最后查到是某几个GPIO没设置成模拟输入模式引脚上悬空产生漏电流。这些都是数据手册不会主动提醒的小细节要靠电流表一点一点量。6. 常见问题排查与避坑技巧实录现象常见原因我的处理办法GPS一直搜不到星天线方向不对、在室内、波特率没对上把天线朝向窗边确认串口波特率9600看有没有GGA语句输出GSM注册不上网络SIM卡接触不良、天线虚焊、信号差用ATCREG?查询检查SIM卡卡座的供电引脚天线焊点重新补焊短信发不出去AT指令顺序错、0x1A发错、电源瞬间跌落严格按CMGF、CMGS、内容、0x1A的顺序加大模块电源电容跌倒误报频繁阈值过低、振动干扰、佩戴松动提高冲击阈值确认姿态和静止判据没有失效重新固定手环APP收不到数据蓝牙波特率不匹配、帧格式没对齐统一模块和串口配置为9600用蓝牙调试助手看原始帧内容手电筒灯珠过热限流电阻太小、PWM占空比过高按LED额定电流重新计算限流电阻长时间点亮时限制最大占空比除了表格里的还有几个不试不知道的经验。第一GSM模块的天线不能贴着地线和电池放我试过把天线压在锂电池旁边信号强度掉得厉害。第二GPS模块的串口和蓝牙模块的串口如果都连着同一个调试口调试的时候容易互相干扰最好用不同波特率或者轮流断开。第三按键消抖一定要做手环在户外振动环境里按键引脚会不断产生抖动不做消抖就会误触手电筒白白耗电。另外建议给所有模块的串口线加一个简单的分压或电平匹配。虽然很多模块标称3.3V兼容但部分GSM模块的串口是2.8V逻辑混用时可能出现“能收到但回不了数据”的怪现象。量一下空闲电平和发送电平常规做法能省很多排查时间。最后给两句实际体会这类组合型项目做完之后我的核心感受是先定模块间通信协议再写代码比边写边改舒服太多。跌倒检测算法这种跟人相关的功能一定要用真实动作反复测试别只跑通逻辑就收工。真要给老人用宁可容忍偶尔误报也好过漏报一次同时务必在文案里注明这是辅助提醒设备。如果你也准备照着这个思路做类似的手环建议先从MPU6050的串口日志看起把一条完整的数据链路摸清楚再讲算法路会顺很多。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑