Let'sdo2025年第2期—智能手环DIY成果贴 Featherboard 健康监测系统开发
源代码:FTHR_I2C.zip
一、项目概述
本项目基于 Maxim MAX78000FTHR 开发板,利用 MaximMicrosSDK 和 VSCode 开发环境,实现了一个集成 RGB 灯控制、OLED 信息显示、MAX30102 心率血氧监测及 RTC 时间显示的健康监测系统。系统通过按键交互实现菜单导航,可在不同功能界面间切换,具备良好的用户交互体验。
核心功能
RGB LED 颜色循环显示
OLED 屏幕信息展示
MAX30102 传感器数据采集与健康参数计算
实时时钟 (RTC) 显示功能
菜单交互系统
二、系统设计
微控制器与外设连接:
RGB LED:通过 I2C 接口连接到 PMIC (MAX20303),地址 0x28
OLED 屏 (SSD1306):通过 I2C 接口连接,地址 0x3C
MAX30102 传感器:通过 I2C 接口连接,用于采集心率和血氧数据
按键 (SW1-SW2):连接到 GPIO 引脚,实现菜单控制
RTC:使用芯片内部实时时钟模块
关键引脚定义:
// 按键引脚定义 #define SW1_PORT MXC_GPIO0 #define SW1_PIN 8 #define SW2_PORT MXC_GPIO0 #define SW2_PIN 6 // I2C配置 #define I2C_FREQ 100000 // I2C通信频率100kHz
三、开发环境搭建
软件环境及配置,按照刘工的指导下载了SDK并使用Vscode进行开发,这里就不再详细描述。
开发工具:Visual Studio Code
SDK:Analog Devices MSDK (Maxim Micros SDK)
四、软件实现
在 VSCode 中打开FTHR_I2C 的demo项目文件夹,这个项目用I2C实现了RGB灯的闪烁功能,再此基础上完成项目要求的全部基础任务及进阶任务:增加菜单制作,增加 RTC 时间的显示
1. 核心功能实现
(1) RGB LED 控制
通过I2C控制 PMIC 芯片驱动蓝绿红三色 RGB LED,实现 8 种颜色循环显示:
void SetLEDs(int state) { int error; mxc_i2c_req_t reqMaster; reqMaster.i2c = PMIC_I2C; reqMaster.addr = PMIC_SLAVE_ADDR; reqMaster.tx_buf = tx_buf; reqMaster.tx_len = LED_SET_LEN; reqMaster.rx_buf = NULL; reqMaster.rx_len = 0; reqMaster.restart = 0; tx_buf[0] = LED_SET_REG_ADDR; tx_buf[1] = (uint8_t)((state & PMIC_LED_BLUE) << 5); tx_buf[2] = (uint8_t)((state & PMIC_LED_RED) << 4); tx_buf[3] = (uint8_t)((state & PMIC_LED_GREEN) << 3); if ((error = MXC_I2C_MasterTransaction(&reqMaster)) != 0) { printf("Error writing to PMIC: %d\n", error); MXC_I2C_Stop(PMIC_I2C); // 出错释放总线 // while (1) {} } MXC_I2C_Stop(PMIC_I2C); // 正常后释放总线 } SetLEDs(i); i = (i + 1) % 8;
(2) OLED 显示功能
调用以前SSD1306相关函数实现字符显示、清屏、等基础功能,并用于菜单和数据展示:
(3) MAX30102 传感器数据处理
采集传感器数据并计算心率和血氧值:根据手册在该网站下载MAXREFDES117的软件包,包含了MAX30102相关驱动及心率与血氧的算法:
https://developer.mbed.org/teams/Maxim-Integrated/code/RD117_MBED/;
具体方法如下:
心率检测:利用血液流动时血管容积变化对光的吸收差异(PPG 信号),通过检测信号峰值间隔计算心率。
血氧饱和度(SpO₂)检测:基于氧合血红蛋白(HbO₂)和脱氧血红蛋白(Hb)对红光(660nm)和红外光(940nm)的吸收特性差异,通过计算两种光信号的比值估算 SpO₂。
二、算法流程
1. 数据采集与预处理
数据采集:通过 MAX30102 传感器同步采集红光和红外光信号,每组采样包含 500 个数据点(BUFFER_SIZE = FS * 5,采样率FS = 100Hz,即 5 秒数据),存储在aun_red_buffer(红光)和aun_ir_buffer(红外光)中。
滑动窗口更新:为保证实时性,采用滑动窗口机制:每秒执行一次,每次保留前 400 个历史数据,新增 100 个最新数据(get_data_show函数),始终维持 500 个数据点用于计算。
2. 信号预处理
滤波与降噪:代码中定义了汉明窗(HAMMING_SIZE = 5),用于对原始信号进行平滑处理,减少高频噪声干扰。
极值归一化:计算信号的最大值(un_max)和最小值(un_min),通过(信号值 - 最小值)/(最大值 - 最小值)归一化处理,突出脉搏波动的 AC 分量(动态变化部分),抑制 DC 分量(静息组织吸收的恒定部分)。
3. 心率计算
峰值检测:通过maxim_find_peaks系列函数(maxim_peaks_above_min_height、maxim_remove_close_peaks)检测 PPG 信号中的峰值(对应心脏收缩期),筛选出高度足够、间隔合理的有效峰值。
心率计算:根据峰值间隔时间(单位:秒),通过公式心率 = 60 / 峰值间隔计算。例如,若峰值间隔为 1 秒,心率为 60 BPM。代码中通过maxim_sort_indices_descend对峰值排序,确保结果稳定性。
4. 血氧饱和度(SpO₂)计算
比值计算:利用红光和红外光 AC 分量的比值(Ratio = AC_red / AC_ir),其中 AC 分量为信号动态波动部分(剔除 DC 分量后的变化量)。
查找表映射:代码中注释提到预计算的uch_spo2_table查找表,该表基于经验公式-45.060*Ratio² + 30.354*Ratio + 94.845生成,通过计算得到的Ratio值查表直接获取 SpO₂。
5. 有效性验证
算法通过ch_hr_valid和ch_spo2_valid标志位判断结果有效性(1 为有效,0 为无效)。例如,心率需在 30-250 BPM 范围内,SpO₂需在 70-100% 范围内,且峰值间隔需稳定(排除噪声导致的错误峰值)。
三、代码核心函数
maxim_heart_rate_and_oxygen_saturation:算法入口函数,输入红外和红光数据缓冲区,输出心率、SpO₂及有效性标志。
maxim_find_peaks:峰值检测核心函数,筛选符合条件的信号峰值。
get_data_show:数据更新与计算接口,通过滑动窗口更新数据并调用核心算法,返回最终心率和 SpO₂值。
该算法通过硬件采集与软件信号处理结合,实现了心率和血氧的实时监测,兼顾精度与实时性,适用于便携式健康监测设备。
(4) RTC 实时时钟
初始化并获取实时时间,实现时间时分秒显示功能:
(5) 菜单系统
通过按键实现菜单导航,支持主菜单、按下SW1进入时间显示菜单、按下SW2进入心率监测菜单实现界面切换:
五、总结与展望
本项目成功实现了基于 MAX78000FTHR 开发板的健康监测系统,集成了 RGB 灯控制、OLED 显示、心率血氧监测和 RTC 时间显示等功能。通过菜单系统实现了良好的用户交互,各项功能运行稳定。
未来可进一步优化:利用了 MAX78000 的 NPU 硬件加速能力,将传统生理信号采集升级为智能健康监测。
通过本项目,深入掌握了 MaximMicrosSDK 的使用方法,熟悉了 I2C 外设驱动开发和嵌入式系统菜单设计,为后续更复杂的嵌入式应用开发奠定了基础。