1. 项目概述与设计思路
这个基于STM32的智能手环项目,主要解决老年人跌倒后的及时报警和定位问题。作为一名嵌入式开发者,我在实际开发中发现市面上很多老人跌倒报警设备存在误报率高、定位不准的问题。这个设计通过多传感器融合和合理的逻辑判断,实现了更可靠的跌倒检测系统。
核心功能模块包括:
- 跌倒检测:ADXL345加速度传感器实时监测姿态
- 报警系统:蜂鸣器本地报警+GSM短信远程报警
- 定位功能:GPS/北斗双模定位
- 附加功能:高亮LED手电筒
- 手机APP:位置显示和设置管理
整个系统的设计难点在于如何平衡灵敏度和误报率。经过多次实测,我们发现将报警触发条件设置为"持续平放状态超过15秒"是最优解,既能捕捉真实跌倒情况,又能避免日常活动导致的误报。
2. 硬件设计与选型解析
2.1 主控芯片选择
采用STM32F103C8T6作为主控,这款芯片具有:
- 72MHz主频,足够处理传感器数据
- 丰富的GPIO和外设接口
- 低功耗模式支持
- 成本优势明显
提示:如果预算允许,可以考虑STM32L系列,功耗表现会更优秀。
2.2 传感器模块选型
ADXL345三轴加速度传感器是我们的核心选择,原因在于:
- 数字输出,I2C/SPI接口,方便与STM32通信
- ±16g量程可调,适合跌倒检测场景
- 内置运动检测功能,减轻MCU负担
- 低功耗特性(测量模式下40μA)
实际使用中,我们将其安装在PCB板的一角,确保能够准确检测板子的姿态变化。
2.3 通信模块配置
2.3.1 GSM模块
选用SIM800L模块,主要考虑:
- 支持四频850/900/1800/1900MHz
- 内置TCP/IP协议栈
- 小巧的尺寸(24*24mm)
- 成本低廉
接线示意图:
c复制// STM32与SIM800L连接
PA2(TX) -> SIM800L_RX
PA3(RX) -> SIM800L_TX
// 注意需要电平转换,SIM800L是3.3V逻辑
2.3.2 GPS模块
采用ATGM336H模块,优势在于:
- 支持GPS/北斗双模定位
- 高灵敏度(-165dBm)
- 内置天线
- 冷启动时间<35s
注意:GPS天线必须放置在露天位置,室内信号极差。
2.4 电源设计
系统需要稳定的5V/2A电源,我们采用:
- 18650锂电池(3.7V)作为主电源
- TP4056充电管理芯片
- MT3608升压芯片(3.7V→5V)
实测表明,这种方案可以满足:
- GSM模块发送短信时的瞬时大电流需求
- 系统长时间工作的稳定性
- 充电安全性
3. 软件设计与实现
3.1 系统主流程
c复制void main() {
hardware_init(); // 硬件初始化
gsm_init(); // GSM模块初始化
gps_init(); // GPS模块初始化
while(1) {
check_fall_status(); // 跌倒检测
check_button(); // 按键检测
led_indicator(); // 状态指示
}
}
3.2 跌倒检测算法
核心判断逻辑:
- 读取ADXL345的三轴加速度值
- 计算板子与垂直方向的夹角
c复制float calculate_angle(float x, float y, float z) {
return atan2(sqrt(y*y + z*z), x) * 180/PI;
}
- 如果角度>70度(接近水平)开始计时
- 持续时间超过15秒触发报警
3.3 GSM短信处理
短信发送流程:
- 等待模块初始化完成(约5-10秒)
- 获取GPS位置信息
- 格式化短信内容
c复制char msg[100];
sprintf(msg, "ALERT! Elder fall detected at: Lat:%f,Lng:%f", latitude, longitude);
- 发送AT指令
c复制AT+CMGF=1\r\n // 设置文本模式
AT+CMGS="138xxxxxxx"\r\n // 设置目标号码
> msg_content\r\n // 输入消息
0x1A // Ctrl+Z发送
3.4 GPS数据处理
GPS数据解析示例(NMEA-0183协议):
c复制void parse_gps(char* gps_data) {
if(strstr(gps_data, "$GPRMC")) {
// 解析RMC语句获取经纬度
sscanf(gps_data, "$GPRMC,%*f,%*c,%f,%*c,%f,%*c", &latitude, &longitude);
}
}
4. 电路设计与PCB布局
4.1 关键电路设计
4.1.1 传感器接口电路
code复制ADXL345接线:
VCC -> 3.3V
GND -> GND
SCL -> PB6(I2C1_SCL)
SDA -> PB7(I2C1_SDA)
4.1.2 高亮LED驱动电路
采用MOSFET驱动大功率LED:
code复制LED+ -> MOSFET漏极
MOSFET栅极 -> PB0
MOSFET源极 -> GND
4.2 PCB布局要点
- ADXL345应安装在板子一角,远离其他干扰源
- GSM天线区域要预留足够的净空区
- GPS模块尽量靠近板边,方便天线布置
- 电源走线要足够宽(建议>1mm)
- 为减少干扰,模拟和数字地要单点连接
5. APP设计与实现
5.1 功能概述
APP主要功能:
- 显示设备上报的位置信息
- 设置接收报警短信的手机号
- 手动获取当前位置
- 历史位置记录
5.2 关键代码实现
5.2.1 短信解析
java复制// Android短信接收处理
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")){
Bundle bundle = intent.getExtras();
if(bundle!=null){
Object[] pdus = (Object[])bundle.get("pdus");
for(Object pdu : pdus){
SmsMessage msg = SmsMessage.createFromPdu((byte[])pdu);
String text = msg.getMessageBody();
if(text.contains("ALERT")){
// 提取经纬度
Pattern pattern = Pattern.compile("Lat:(.*?),Lng:(.*?)");
Matcher matcher = pattern.matcher(text);
if(matcher.find()){
double lat = Double.parseDouble(matcher.group(1));
double lng = Double.parseDouble(matcher.group(2));
showOnMap(lat, lng); // 在地图上显示
}
}
}
}
}
}
5.2.2 地图显示
使用高德地图API显示位置:
java复制// 初始化地图
mMapView = findViewById(R.id.map);
mAMap = mMapView.getMap();
// 添加标记
MarkerOptions markerOpt = new MarkerOptions();
markerOpt.position(new LatLng(latitude, longitude));
markerOpt.title("跌倒位置");
mAMap.addMarker(markerOpt);
// 移动视角
mAMap.moveCamera(CameraUpdateFactory.newLatLngZoom(
new LatLng(latitude, longitude), 15));
6. 系统调试与优化
6.1 常见问题排查
-
GSM模块无法初始化
- 检查电源是否达到2A峰值电流
- 确认SIM卡已正确插入
- 检查天线是否连接良好
-
GPS定位慢
- 确保天线在露天位置
- 检查供电电压是否稳定
- 尝试冷启动(清除星历数据)
-
跌倒误报率高
- 调整角度阈值(建议60-80度)
- 优化计时参数(10-20秒)
- 增加多轴传感器数据融合
6.2 性能优化建议
-
低功耗优化
- 使用STM32的睡眠模式
- 间歇性唤醒GPS模块
- 动态调整传感器采样率
-
报警可靠性提升
- 增加多级报警机制
- 实现短信发送重试功能
- 添加电池电量监测
-
用户体验改进
- 增加震动反馈
- 优化取消报警的按键操作
- 提供更友好的状态指示灯
7. 实际应用中的经验分享
经过三个月的实地测试,我们发现以下几个实用技巧:
-
设备佩戴位置很重要,建议放在腰部口袋,这样既能准确检测跌倒,又不容易误触取消按钮。
-
在GSM模块初始化阶段(约5秒),系统不应处理任何传感器数据,否则容易导致死机。
-
GPS定位在阴雨天气可能变差,这时可以采用最后已知位置+时间戳的方式提供参考位置。
-
高亮LED的驱动电路需要做好散热,连续使用超过10分钟建议自动降亮度。
-
定期(如每月一次)检查设备的电池状态和天线连接,确保关键时刻能正常工作。
这个项目最让我自豪的是它的实用性——已经帮助多位老人及时获得了救助。在开发过程中,最大的收获是认识到硬件产品的可靠性设计远比功能丰富更重要。每一个参数的选择、每一处电路的设计,都可能在实际使用中产生重大影响。