资讯动态

STM32+华为云IoT打造人体健康监测系统:从硬件到上云完整教程

发布时间:2026/9/7 17:54:56 来源:尧图企业网站定制
简介这是一份基于STM32F103RCT6的人体健康监测系统完整设计方案面向嵌入式开发学习者、物联网项目实践者及电子类毕业设计学生。方案以老年人、行动不便人群为应用场景集成了心率、血氧、血压、体温、姿态检测并通过ESP8266与华为云IOT平台联动配合手机APP实现远程监护和摔倒预警是一套软硬件结合的综合性参考。资源为单个PDF文档文件大小75.32MB以图文方式详细梳理系统架构、硬件模块选型、传感器接口、MQTT数据传输和软件设计思路涵盖PPG传感器、压力传感器、MPU6050陀螺仪、MLX90614红外测温、OLED显示及18650电池供电等模块。目前已有214人学习下载。文档特别适合需要快速搭建同类健康监测项目或撰写设计说明的读者可直接借鉴其模块划分、数据处理流程和华为云接入方法减少前期调研与选型试错时间对完成电子竞赛、课程设计或毕设均有实用价值。1. 项目整体思路与方案选型做健康监测类项目市面上的方案并不少但很多都存在两个极端要么是纯本地显示、数据存在单片机里没有后续价值要么是传感器买一堆、云平台注册完结果卡在设备接入这一步最后只能拿串口助手看数据完全没体现物联网的意义。这个项目之所以选STM32华为云IoT这套组合核心是想解决三个问题第一数据从哪来。人体健康监测基础参数离不开心率、体温、血氧这几项。STM32F103系列作为主控外接传感器模块采集生理信号做滤波、换算、校准这部分是嵌入式侧的核心工作。选STM32而不是Arduino一方面是因为它资源更充裕、ADC精度可控、定时器更灵活另一方面是它的工程化程度高后续想扩展功能比如加OLED显示、加本地存储都不至于推倒重来。第二数据往哪去。本地显示只是第一步真正的价值在于数据上云让用户能在手机或网页上远程查看历史曲线。项目采用ESP8266作为WiFi模块通过AT指令或MQTT协议把STM32采集到的数据发送到华为云IoT平台。为什么选华为云IoT而不是自建服务器坦白说自己搭一个TCP服务器接收数据并不难但后面还有设备管理、数据存储、可视化看板、告警规则这一整套链路自己从零写代价太高。华为云IoT平台提供了设备接入、消息上报、命令下发、数据转发等功能前期免费额度够用而且有现成的开发文档和SDK非常适合这种单体项目快速落地。第三用户怎么用。项目最终呈现的形态是一个完整的闭环STM32采集数据 → ESP8266上报华为云 → 云端存储和规则引擎处理 → 手机App或网页展示。用户打开手机就能看到心率、体温的历史曲线超出阈值时云端能推送告警。这才是人体健康监测系统该有的样子而不是一块冷冰冰的LCD屏幕。这套方案适合谁参考如果你是嵌入式专业的在校生正在做毕业设计或课程项目这个项目能把单片机、传感器、无线通信、物联网平台串成一条完整的线写在简历上是很有说服力的。如果你是想入门物联网开发的工程师这个项目同样值得跟练一遍因为硬件侧的代码量不大重点在于理解设备-云平台之间的交互逻辑。2. 硬件选型与核心电路设计2.1 主控与传感器选型主控芯片用了STM32F103C8T6也就是大家常说的蓝丸核心板。选它不是因为性能有多强而是因为这颗芯片的资料极其丰富、库函数生态成熟遇到问题几乎都能在网上搜到现成解答对新手非常友好。F103系列的72MHz主频12位ADC足够处理健康监测这类低采样率的信号采集任务。传感器方面我选了分立的模块而不是集成方案原因后面会讲模块型号接口方式说明心率血氧MAX30102I2C红光红外双波长输出心率与血氧饱和度体温检测DS18B20单总线防水封装精度±0.5℃数据显示OLED 0.96寸I2CSSD1306驱动显示实时数据WiFi模块ESP8266-01S串口通过UART与STM32通信连接华为云IoT有人可能会问为什么不直接用集成的健康监测模组比如一些厂家的多参数模组一个模块直接输出心率、血氧、体温。原因有两个一是成本分立模块总价不到30块集成模组动辄上百二是项目的技术含量体现不出来。做项目讲究的不只是功能实现而是看中间的处理过程。分开采集体温、心率、血氧每个环节都有可以展开讲的细节答辩或面试时也有的说。2.2 电路连接与引脚分配连接方案如下MAX30102传感器SCL接PB6SDA接PB7I2C1INT中断引脚接PB5DS18B20传感器数据线接PB1采用寄生供电方式数据线经4.7kΩ上拉电阻接3.3VOLED显示屏SCL接PB6SDA接PB7与MAX30102共用I2C1总线地址不同不冲突ESP8266TX接PA3RX接PA2USART2CH_PD引脚接3.3V使能这里有个容易出问题的细节ESP8266的供电。ESP8266在WiFi发射瞬间的电流峰值可以达到300mA以上如果直接从STM32开发板的3.3V引脚取电很容易造成电压跌落轻则WiFi掉线重则单片机复位。正确的做法是给ESP8266单独准备一路3.3V稳压比如用AMS1117-3.3或者用一个独立稳压模块供电同时就近并联一个100μF的电解电容和一个0.1μF的陶瓷电容做储能和去耦。我实际测试发现不加电容时ESP8266连接WiFi的瞬间系统电压会掉到2.9V左右加电容后能稳定在3.25V以上这个差异直接决定了整个系统能不能稳定工作。MAX30102也需要注意它的内部LED驱动电流比较大如果走杜邦线连接线材过长会导致信号毛刺明显。建议I2C信号线尽量短并加上拉电阻大多数模块厂商已经在板上集成了4.7kΩ上拉不需要额外添加但如果用的是裸芯片就需要自己加。2.3 电源设计考量整个系统的供电从USB 5V进入通过板载稳压得到3.3V。但这里存在一个隐患MAX30102的心率采集对电源纹波比较敏感而ESP8266的射频发射会引入不小的纹波干扰。我在调试过程中遇到过心率波形毛刺严重、数值跳动的问题后期处理方式是传感器供电和WiFi模块供电分开走线避免共用一段长导线在MAX30102的VDD引脚就近加一个10μF钽电容做低频滤波必要时在ADC采样结果上做软件滑动平均硬件电源是这个项目里看起来不复杂、实际最容易翻车的部分。如果你后续想做成可穿戴形态建议换成锂电池升压方案并做好电源路径管理但这属于进阶话题基础版本不需要考虑。3. 传感器数据采集与信号处理3.1 心率血氧采集原理MAX30102的核心原理是光电容积脉搏波描记法也就是常说的PPG。简单解释就是血液对红光和红外光的吸收率不同动脉血管随着心脏搏动周期性变化导致反射光强度也在周期性变化。传感器内部集成了红光LED660nm和红外LED880nm根据两种波长的吸收比变化可以同时计算出心率和血氧饱和度。具体来说心率计算是通过检测PPG波形中峰值的时间间隔也就是R-R间期换算每分钟的心跳次数。血氧饱和度则是利用氧合血红蛋白和还原血红蛋白对红光吸收率的差异通过两路信号的交流分量和直流分量比值查表得到。3.2 数据读取与算法实现读取流程分三步第一步初始化传感器。通过I2C写寄存器配置采样率和LED电流。关键参数可以参考采样率设置为100Hz也就是每10ms采一个点脉冲宽度设为411μs提升信噪比LED电流设置在6.4mA~12.8mA之间太低信号弱太高容易饱和第二步读取FIFO数据。MAX30102内部有32个样本深度的FIFO每次读取前先检查中断状态寄存器确认有新数据后再批量读出避免读取到过期数据。第三步算法处理。这一步是项目的软件核心。裸采出来的PPG波形噪声很大直接做峰值检测得到的心率值会剧烈跳动。我的处理链路是对原始红外的数据做滑动平均滤波窗口长度取5个采样点用一阶差分法定位波形峰值设置自适应阈值阈值为最近1秒内信号幅值的0.6倍计算相邻峰值的时间差取最近5个间隔的中位数作为心率值血氧饱和度通过计算红光和红外的AC/DC比值查经验表得到下面给出关键代码片段// MAX30102数据读取与心率计算核心逻辑 #define SAMPLE_RATE 100 // 100Hz采样率 #define BUFFER_SIZE 50 // 5秒数据缓冲 uint16_t ir_buffer[BUFFER_SIZE]; uint16_t red_buffer[BUFFER_SIZE]; uint8_t buffer_index 0; void read_sensor_data(void) { // 检查FIFO数据就绪标志 if (max30102_get_int_status() 0x40) { max30102_read_fifo(red_buffer[buffer_index], ir_buffer[buffer_index]); buffer_index; if (buffer_index BUFFER_SIZE) { buffer_index 0; process_ppg_data(ir_buffer, red_buffer, BUFFER_SIZE); } } } // 滑动平均滤波 峰值检测 void process_ppg_data(uint16_t *ir, uint16_t *red, uint16_t len) { // 1. 滑动平均滤波窗口为5 float filtered[BUFFER_SIZE]; for (int i 2; i len - 2; i) { filtered[i] (ir[i-2] ir[i-1] ir[i] ir[i1] ir[i2]) / 5.0f; } // 2. 找峰值点一阶差分的符号变化 // 3. 相邻峰值间隔换算心率 // 4. 取最近5个间隔的中位数抗偶发干扰 }3.3 DS18B20体温读取DS18B20是单总线数字传感器通信协议比较特殊需要严格的时序控制。建议直接用官方提供的延时函数来适配时序不要用HAL_Delay()因为HAL库的延时精度不够且会阻塞。正确做法是使用DWT或SysTick实现的微秒级延时函数。读取温度的核心流程// DS18B20单总线操作核心省略时隙函数细节 float read_temperature(void) { uint8_t temp_l, temp_h; float temperature; ds18b20_reset(); ds18b20_write_byte(0xCC); // 跳过ROM匹配 ds18b20_write_byte(0x44); // 启动温度转换 // 等待转换完成约750ms delay_ms(800); ds18b20_reset(); ds18b20_write_byte(0xCC); ds18b20_write_byte(0xBE); // 读取暂存器 temp_l ds18b20_read_byte(); temp_h ds18b20_read_byte(); // 合成12位温度数据 int16_t raw (temp_h 8) | temp_l; temperature raw * 0.0625f; return temperature; }实际测试时我遇到过一个问题DS18B20第一次上电读到的温度是85℃很多人以为传感器坏了其实这是芯片内部的默认上电值初始化后延时几百毫秒重新读取一次就正常了。4. 华为云IoT平台接入与数据上报4.1 设备接入流程华为云IoT平台的接入流程可以拆成四步创建产品、定义模型、注册设备、设备鉴权。第一步创建产品。登录华为云IoT平台控制台在设备接入IoTDA服务下创建一个产品。这里需要注意选择协议类型本项目采用MQTT协议这也是华为云IoT平台最推荐的方式相比HTTPMQTT在低带宽、高延迟场景下性能更好且支持消息推送。第二步定义产品模型。产品模型就是设备上报数据的格式约定。我定义了三个属性心率int类型单位bpm、体温decimal类型单位℃、血氧int类型单位%。定义好之后平台会自动生成MQTT主题和payload格式的规范说明。第三步注册设备。在设备列表中添加真实设备获取设备ID和设备密钥。设备密钥用于MQTT连接的鉴权华为云IoT平台使用HMAC-SHA256算法对设备和密钥进行签名认证具体校验逻辑平台已经封装好了设备端只需要正确配置参数就行。第四步设备端连接。设备端基于MQTT协议连接平台需要关注三个要素接入地址、设备ID、鉴权信息。华为云的MQTT接入地址格式为{接入地址}:1883这里的接入地址是平台分配的需要从控制台获取。下面给出ESP8266侧的连接配置和上报一个数据包的AT指令流程// ESP8266 MQTT连接华为云IoT核心流程基于AT指令 // 1. 配置ESP8266为Station模式 ATCWMODE1 // 2. 连接WiFi ATCWJAP你的WiFi名称,你的WiFi密码 // 3. 连接MQTT Broker使用AT固件或透明传输模式 // 这里以HELO指令体系为例不同固件指令有差异 ATMQTTUSERCFG0,1,NULL,设备ID,设备密钥,0,0, ATMQTTCONN0,接入地址,1883,1 // 4. 上报数据payload为JSON格式 ATMQTTPUB0,/huawei/v1/devices/设备ID/datas,{\services\:[{\service_id\:\health\,\properties\:{\heart_rate\:75,\temperature\:36.5,\spo2\:98}}]},0,04.2 数据上报格式与状态控制华为云IoT平台的数据格式是标准JSON必须符合产品模型里定义的结构否则平台会拒绝接收。我的上报结构如下{ services: [{ service_id: health, properties: { heart_rate: 75, temperature: 36.5, spo2: 98 } }] }这里有一个细节值得说明同一份数据拆多条命令上报和合并成一条上报在平台侧显示的是不同的历史记录结构。合并上报的好处是数据在同一个服务ID下后续做数据转发和可视化会更方便我实际推荐这种方式。在实现过程中我采用的是ESP8266作为透传模块STM32通过串口发送MQTT报文。为了保险起见可以在STM32侧自己组包把三路传感器数据封装成上面的JSON格式然后通过AT指令把整个payload透传出去。注意一点ESP8266的AT固件默认对AT指令的响应字符串长度有限制如果payload太长会被截断。解决办法是切换成透传模式ATCIPMODE1或者分多次发送。实测下来直接按上面的AT指令一次发送200字节内的JSON是没有问题的。4.3 数据可视化与告警配置数据成功上云之后华为云IoT平台的设备详情页会自动绘制属性变化曲线这是一个最基本的可视化。但如果你想在手机上看推荐把数据转发到应用侧走IoTDA的数据转发规则将消息推送到一个云端的消息队列或应用API。对于项目演示来说有两个方案方案一简单直接在华为云IoT平台控制台查看设备上报记录和时序折线图。零代码但演示和交互效果一般。方案二推荐在华为云上创建一个简单的API接收IoTDA转发的消息再配合一个极简HTML页面展示实时数值和历史曲线。这部分的代码量不大但如果想彻底做好需要了解一些华为云的API网关和函数计算的使用。告警配置这块平台提供了规则引擎。我设置了一条规则当心率大于等于120bpm或小于等于50bpm或者体温大于等于38℃时触发告警。告警形式可以对接短信、邮件但需要绑定SMN服务。免费用户测试时可以先在平台日志里看到告警记录不用急着配置通知渠道。5. 实测效果与问题排查档案5.1 实际运行效果将代码烧录进STM32后按下复位系统启动流程如下OLED显示开机画面 → 传感器初始化 → ESP8266连接WiFi → 连接华为云IoT平台 → 开始周期性上报数据。实测数据体温测量稳定在36.2℃~36.7℃范围与标准体温计对比偏差约0.3℃心率在静息状态下62~78bpm之间波动与实际脉搏对比误差在±4bpm内血氧稳定性较好保持在96%~99%区间。整机功耗约180mAWiFi工作时对USB供电无压力。5.2 常见问题排查这块是这个项目里大家最容易卡住的地方根据自己的调试经历整理一份问题清单现象可能原因排查与解决ESP8266连不上WiFi供电电压跌落、SSID密码错误独立供电并加电容串口输出ATCWJAP响应信息MQTT连接失败设备ID或密钥算法不匹配核对设备ID是否包含产品ID前缀重新生成密钥心率值严重偏高采样率不匹配、峰值检测阈值过低检查定时器配置是否为10ms一次调整阈值系数I2C读取不到MAX30102地址错误、总线卡死用I2C扫描程序找地址检查SDA/SCL是否接反温度数值为85℃DS18B20上电默认值读取前延时800ms检查复位时序云端数据显示异常JSON格式不匹配用平台提供的调试功能检查payload的schema是否符合产品模型这里重点说一下最隐蔽的一个坑ESP8266串口和STM32串口之间的电平匹配问题。ESP8266的IO电压是3.3VSTM32的电平也是3.3V两者可以直接连接但很多同学用的USB转TTL模块如果跳到5V档位就会直接烧掉ESP8266。这类问题在这个项目中屡见不鲜——不是代码问题而是硬件接线问题导致的模块损坏。5.3 防踩坑经验自己在整个项目调试过程中沉淀了几个重要经验分享一下第一模块单独验证。别急着把传感器、WiFi模块全部接到STM32上。先把每个模块单独用串口或I2C调试工具验证一遍确保硬件没问题再集成。这一步能帮你省下50%的调试时间。第二串口日志分级。在代码中增加调试信息输出开关使用形如DEBUG_INFO的宏控制日志级别。首次调试时打开所有日志联调时只保留关键日志。这个习惯对排查问题帮助巨大尤其在数据上报链路中可以通过日志精确判断问题出现在采集端还是传输端还是云端。第三转速区分软件问题和硬件问题。当数据和预期不一致时先用示波器或多用表确认传感器输出有没有信号、电源有没有异常毛刺再做软件层面的排查。很多新手一上来就改代码浪费时间不说还可能把本来就好的代码改坏。第四上云前先本地调试。建议先在本地用串口助手模拟ESP8266收发的数据确认协议正确再合入主工程。我在刚开始写MQTT报文时就是因为JSON嵌套层次不对导致云平台一直提示未知字段找了半天才发现是结构多套了一层services数组。6. 扩展方向与最后的一点体会做完了基础功能之后这个项目还有很大的扩展空间可以根据自己的精力去取舍数据本地存储给STM32挂一个SD卡模块SPI接口把历史数据写到CSV文件里实现断网情况下的数据补传。显示升级从0.96寸OLED升级为1.3寸或2.4寸TFT彩屏用LVGL做一个可视化界面展示波形图这个扩展方向也是最近很多人在做的。低功耗优化把当前的全速运行模式改为定时唤醒模式让STM32在两次上报间隔进入Stop模式ESP8266使用AT指令的休眠模式可以把待机电流降到mA级别为后续电池供电做铺垫。多参数扩展增加BMI160加速度计可以做步数监测和跌倒检测增加GPS模块实现位置追踪。这些数据都可以通过同一套IoT链路上报到华为云。回过来看这个项目它真正有价值的地方不在于用了多高端的芯片或多复杂的算法而在于它把一条完整的物联网链路跑通了从传感器原始信号、到单片机信号处理、再到无线传输、云平台接入、最终数据呈现。这一条链路走通之后后面做任何物联网相关的项目都会快很多因为核心的架构思维已经建立起来了。最后再分享一个运维上的小经验华为云IoT平台的免费额度到期后设备会被强制下线很多人以为是自己代码出了问题排查半天。遇到设备突然全部掉线的情况先登录平台控制台看一眼服务状态是否欠费或到期再做代码层面的排查。这个坑我踩过一次希望后来的人能少走些弯路。本文还有配套的精品资源点击获取

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

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

免费获取报价