1. 项目概述
这个基于STM32的心率血氧手环项目是我最近完成的一个嵌入式系统设计,它能够实时监测人体多项生理指标,并在异常情况下发出警报。作为一个经常熬夜加班的程序员,我一直想为自己做一个健康监测设备,这个项目正好满足了我的需求。
手环的核心功能包括:
- 实时监测心率和血氧饱和度
- 计步功能记录日常活动量
- 体温监测
- OLED屏幕显示各项数据
- 异常数值声光报警
- 蓝牙连接手机APP实现远程监控
整个系统以STM32F103C8T6单片机为核心,搭配多种传感器模块实现上述功能。下面我将详细介绍这个项目的设计思路和实现过程。
2. 硬件设计详解
2.1 核心控制器选型
选择STM32F103C8T6作为主控芯片主要基于以下几点考虑:
- 性能足够:72MHz主频,64KB Flash,20KB RAM,完全能满足数据处理需求
- 外设丰富:多个I2C、UART接口,方便连接各种传感器
- 开发便捷:资料丰富,社区支持好
- 成本低廉:相比其他方案更具性价比
实际使用中,这款芯片的表现确实很稳定,即使在长时间运行的情况下也没有出现死机或数据异常的情况。
2.2 传感器模块设计
2.2.1 心率血氧传感器(MAX30102)
MAX30102是一款集成式光学传感器,通过光电体积描记法(PPG)测量心率和血氧。它的工作原理是:
- 发射红光(660nm)和红外光(880nm)穿透皮肤
- 检测反射光强度变化
- 分析脉搏波形计算心率
- 通过两种光吸收率差异计算血氧饱和度
在PCB布局时需要注意:
- 传感器要尽量靠近皮肤接触面
- 避免强光直射影响测量精度
- I2C线上要加上拉电阻(我用了4.7kΩ)
2.2.2 加速度计(ADXL345)
ADXL345用于实现计步功能,我将其配置为±2g量程,100Hz采样率。计步算法主要流程:
- 读取三轴加速度数据
- 计算合加速度
- 检测峰值超过阈值
- 两次峰值间隔在合理步行周期内(0.2-1秒)
- 计为有效步数
实际测试中,这个算法对正常步行的识别准确率能达到95%以上,但对跑步等剧烈运动还需要优化。
2.2.3 其他传感器
- DS1302时钟模块:提供精确时间,纽扣电池供电保证掉电不丢失
- DS18B20温度传感器:测量体温,单总线接口节省IO资源
- OLED显示屏:128×64分辨率,I2C接口,低功耗
3. 软件系统实现
3.1 系统架构设计
软件采用模块化设计,主要分为以下几个部分:
- 硬件抽象层:封装各传感器驱动
- 数据处理层:实现各种算法(心率计算、计步等)
- 应用层:业务逻辑和用户界面
- 通信层:蓝牙数据传输
这种分层设计使得代码结构清晰,便于维护和扩展。
3.2 关键算法实现
3.2.1 心率计算算法
MAX30102采集到的是原始光强数据,需要经过以下处理:
- 带通滤波(0.5-5Hz)去除噪声
- 寻找波峰位置
- 计算相邻波峰间隔
- 转换为心率值(bpm)
c复制// 伪代码示例
float calculate_hr(uint32_t *samples, int count) {
// 滤波处理
filter(samples, count);
// 寻找波峰
int peaks[20];
int peak_count = find_peaks(samples, peaks);
// 计算平均间隔
float avg_interval = 0;
for(int i=1; i<peak_count; i++) {
avg_interval += (peaks[i]-peaks[i-1]);
}
avg_interval /= (peak_count-1);
// 转换为bpm
return 60.0 * SAMPLE_RATE / avg_interval;
}
3.2.2 血氧计算算法
血氧计算基于红光和红外光吸收率的差异:
- 分别计算两种光的AC/DC分量比
- 通过经验公式计算血氧饱和度
c复制float calculate_spo2(uint32_t *red, uint32_t *ir, int count) {
float red_acdc = acdc_ratio(red, count);
float ir_acdc = acdc_ratio(ir, count);
float ratio = red_acdc / ir_acdc;
// 经验公式
return 110 - 25 * ratio;
}
3.3 蓝牙通信协议
蓝牙模块使用BT04-A,通信协议设计如下:
| 指令 | 格式 | 说明 |
|---|---|---|
| 数据上报 | D,HR,SPO2,TEMP,STEP | 上报当前数据 |
| 设置阈值 | S,TYPE,MIN,MAX | 设置报警阈值 |
| 清零步数 | C | 步数清零 |
| 时间同步 | T,YYMMDDHHMMSS | 同步时间 |
在实现时需要注意:
- 添加校验和确保数据完整性
- 设置超时机制防止通信阻塞
- 数据压缩减少传输量
4. 系统优化与调试
4.1 功耗优化
作为可穿戴设备,低功耗设计非常重要。我采取了以下措施:
-
动态调整传感器采样率:
- 静止时降低采样率
- 检测到运动时提高采样率
-
智能屏幕控制:
- 无操作10秒后降低亮度
- 30秒无操作关闭显示
- 检测到抬手动作自动点亮
-
低功耗模式:
- 夜间时段进入睡眠模式
- 仅保持基础功能运行
通过这些优化,200mAh的电池可以支持约3天的使用。
4.2 抗干扰设计
在实际使用中发现以下干扰问题及解决方案:
-
运动伪影:
- 增加运动状态检测
- 运动时暂停血氧测量
- 使用加速度数据补偿
-
环境光干扰:
- 增加光学遮罩
- 软件滤波算法
- 自动增益调整
-
电磁干扰:
- 优化PCB布局
- 增加去耦电容
- 屏蔽敏感信号线
4.3 精度校准
为了提高测量精度,我建立了校准流程:
-
心率校准:
- 与医用脉搏血氧仪对比
- 记录10组数据
- 计算修正系数
-
血氧校准:
- 在不同血氧水平下测试
- 建立校准曲线
- 分段线性补偿
-
温度校准:
- 水浴法多点校准
- 非线性补偿
- 环境温度补偿
经过校准后,各项指标的精度达到:
- 心率:±2bpm
- 血氧:±2%
- 体温:±0.3℃
5. 使用体验与改进方向
5.1 实际使用效果
经过一个月的日常使用,手环表现稳定:
- 能够准确识别心率异常(如熬夜后心率升高)
- 血氧监测在静止状态下很准确
- 计步功能基本满足日常需求
- 蓝牙连接稳定,数据同步及时
特别是报警功能很实用,有次加班到凌晨,手环检测到血氧偏低发出了警报,提醒我该休息了。
5.2 遇到的问题
-
运动时数据波动大:
- 解决方法:增加运动模式识别,调整算法参数
-
长时间佩戴舒适性:
- 改进腕带材质
- 优化设备重量分布
-
电池续航:
- 优化电源管理策略
- 考虑更大容量电池
5.3 未来改进方向
-
增加ECG功能:
- 需要额外电极
- 更复杂的心电算法
-
睡眠监测:
- 基于加速度和心率变异性
- 睡眠阶段分析
-
云端数据同步:
- 添加WiFi模块
- 开发数据分析平台
-
机器学习应用:
- 异常模式识别
- 健康趋势预测
这个项目从硬件设计到软件开发,再到调试优化,整个过程让我学到了很多。特别是对生物信号处理有了更深入的理解。虽然现在市面上有很多成熟的健康手环产品,但自己动手做一个,并根据自身需求定制功能,这种体验是完全不同的。