拓冰建站拓冰建站
首页 / 资讯中心 / 正文

ESP32与MAX30102健康监测:血氧体温测量实战指南

1. 为什么选ESP32加MAX30102做健康监测1.1 从需求出发一个能落地的健康监测方案长什么样血氧和体温这两个指标在健康监测领域属于基础但极其重要的数据。血氧饱和度反映的是血液携氧能力体温反映的是身体代谢和免疫状态。市面上能测这两项的设备不少但如果你想自己动手做一个或者想理解这类设备到底是怎么工作的ESP32加MAX30102的组合是目前性价比最高、资料最全、上手门槛最低的方案之一。我最初接触这个组合是因为一个朋友的需求他家里有老人想做一个能放在床头的小设备定时采集血氧和体温数据通过手机就能看到趋势变化。市面上的成品要么功能太单一要么数据不开放要么价格虚高。自己动手做的好处是所有数据都在自己手里想怎么处理就怎么处理想加什么功能就加什么功能。这个方案适合谁如果你有基本的电子电路知识会一点Arduino编程那就可以直接上手。如果你完全零基础也没关系我会把每一步都拆开讲清楚包括为什么这么做、参数怎么算、坑在哪里。整个项目的硬件成本大概在五十到一百元之间具体取决于你手头已有的工具和元器件。ESP32这颗芯片在这类项目里的优势非常明显。它自带WiFi和蓝牙双核处理器主频能到240MHz内存也够用关键是社区生态极其丰富。你想把数据传到手机、传到电脑、传到云端都有现成的库和方案。MAX30102则是一个集成了红光和红外LED、光电探测器、光学元件的传感器模块专门用来做心率和血氧测量。它通过I2C接口和主控通信接线简单驱动成熟。温度测量这块方案就多了。可以用MAX30102自带的温度传感器也可以用DS18B20、MLX90614这类独立传感器。我后面会详细对比几种方案的优劣帮你根据自己的需求做选择。1.2 核心器件选型背后的逻辑先说MAX30102。这个模块本质上是一个光学传感器工作原理是光电容积脉搏波描记法。简单说就是血液中的血红蛋白对特定波长光的吸收率会随着血液搏动而变化。含氧血红蛋白和脱氧血红蛋白对红光和红外光的吸收特性不同通过分析两种波长光的吸收比例就能推算出血氧饱和度。MAX30102内部集成了两个LED红光660nm和红外880nm、一个光电二极管、一个18位ADC还有FIFO缓冲区。它通过I2C接口输出原始光强数据你在主控端做算法处理。模块本身还带一个温度传感器精度大概在±1°C左右可以用来做环境温度补偿但不太适合直接测体温。为什么选它而不是别的MAX30100是上一代产品精度和稳定性都不如MAX30102。MAX30105功能更多但价格更贵而且多出来的气体检测功能在这个项目里用不上。MAX30102在精度、价格、资料丰富度之间找到了一个很好的平衡点。ESP32这边我推荐用ESP32-WROOM-32或者ESP32-DevKitC这类开发板。它们自带USB转串口芯片烧录方便引脚引出完整价格也就二三十块钱。如果你手头有ESP32-S3或者ESP32-C3也完全可以用只是引脚定义和库的兼容性需要稍微注意一下。温度传感器我最终选了MLX90614。这是一个红外非接触式温度传感器精度能到±0.5°C测量范围覆盖人体温度区间。它的优势是非接触放在额头上方几厘米就能读数避免了接触式传感器需要贴合皮肤的问题。DS18B20虽然便宜但响应慢而且需要接触测量。MAX30102自带的温度传感器精度不够只能做参考。2. 硬件连接与电路设计要点2.1 引脚分配与I2C总线规划ESP32的I2C引脚是可以自定义的这一点比Arduino Uno灵活很多。我一般习惯用GPIO21作为SDAGPIO22作为SCL这两个引脚在大多数ESP32开发板上都有引出而且位置比较顺手。MAX30102模块的接线很简单VIN接3.3VGND接GNDSDA接GPIO21SCL接GPIO22INT可以不接我们用轮询方式读取。注意MAX30102的工作电压是1.8V到3.3V千万不要接5V否则可能烧毁模块。我见过有人直接接5V结果模块当场冒烟这个坑一定要避开。MLX90614也是I2C接口可以和MAX30102挂在同一条总线上。MLX90614的默认地址是0x5AMAX30102的地址是0x57不冲突。接线也是VIN接3.3VGND接GNDSDA和SCL分别并联到GPIO21和GPIO22。这里有个细节I2C总线需要上拉电阻。大多数模块板载已经带了4.7kΩ或10kΩ的上拉电阻所以直接并联没问题。但如果你买的模块没有上拉电阻或者你发现通信不稳定就需要在SDA和SCL上各加一个4.7kΩ的电阻拉到3.3V。我实测下来总线长度在20厘米以内、只挂两个设备的情况下板载上拉电阻基本够用。电源方面ESP32开发板可以通过USB供电MAX30102和MLX90614都从开发板的3.3V引脚取电。注意ESP32的3.3V引脚输出电流有限大概能到600mA左右这两个传感器加起来功耗不到50mA完全没问题。但如果你还要接显示屏或者其他外设就要算一下总功耗了。2.2 电源噪声与信号完整性处理光学传感器对电源噪声非常敏感。MAX30102的LED驱动电流是脉冲式的峰值电流能到50mA这会在电源线上产生纹波。如果电源质量不好光强读数就会跳动血氧算法就算不准。我的做法是在MAX30102的VIN和GND之间并一个10μF的钽电容和一个0.1μF的陶瓷电容。钽电容负责低频滤波陶瓷电容负责高频去耦。这两个电容要尽量靠近模块的电源引脚引线越短越好。实测下来加了这两个电容之后原始光强数据的噪声明显降低心率计算的稳定性提升了不少。MLX90614对电源噪声的敏感度低一些但我也习惯在它的电源引脚并一个0.1μF的电容。这个传感器内部有稳压电路但外部加一个去耦电容总没坏处。还有一个容易被忽略的点ESP32的WiFi模块工作时会产生射频干扰。如果你发现开启WiFi后传感器读数异常可以尝试把传感器模块远离ESP32的天线区域或者在软件上做多次采样取中值滤波。我一般会把MAX30102放在开发板的正上方或者侧面避免天线正对传感器。2.3 结构设计与佩戴方式如果你要做的是接触式测量手指按在传感器上那结构设计相对简单。MAX30102模块的发光面和接收面在同一侧手指按上去之后光线穿透皮肤组织部分光被血液吸收部分光反射回接收器。关键是要保证手指和传感器之间没有缝隙但又不能压得太紧否则会影响血液循环导致读数失真。我的做法是用一块黑色海绵或者不透光的橡胶垫中间挖一个和传感器窗口差不多大的孔贴在模块表面。手指按上去之后海绵会贴合手指轮廓挡住环境光。环境光干扰是光学测量的一个大问题尤其是日光灯和阳光中的红外成分会直接叠加到信号上。如果你要做非接触式测量比如测额头温度那MLX90614的安装角度就很重要。它的视场角大概是90度测量距离和光斑直径的关系是光斑直径约等于测量距离乘以tan(45°)也就是距离每增加1厘米光斑直径增加约2厘米。测额头温度时距离控制在3到5厘米比较合适太近了光斑太小容易受局部皮肤状态影响太远了光斑太大容易混入环境温度。3. 软件开发环境搭建与核心库解析3.1 Arduino IDE配置ESP32开发环境虽然网上有很多种开发ESP32的方式比如ESP-IDF、PlatformIO、MicroPython但我还是推荐从Arduino IDE入手。原因很简单库多、例子多、上手快。等你把功能跑通了再考虑要不要换更专业的工具链。首先去Arduino官网下载最新版的Arduino IDE。安装完成后打开首选项在“附加开发板管理器网址”里填入ESP32的板管理器地址。这个地址在Espressif的官方文档里能查到我这里就不贴具体链接了你搜“Arduino ESP32 board manager URL”就能找到。然后打开开发板管理器搜索“esp32”安装“Espressif Systems”提供的那个包。安装过程可能需要几分钟取决于你的网络速度。安装完成后在开发板列表里选择“ESP32 Dev Module”或者你实际使用的型号。接下来安装库。MAX30102我推荐用“SparkFun MAX3010x Pulse and Proximity Sensor Library”这个库封装得比较好提供了心率计算和血氧计算的示例代码。MLX90614用“Adafruit MLX90614 Library”简单易用。这两个库都可以通过库管理器直接搜索安装。有一个坑要注意SparkFun的MAX30102库默认使用Wire库进行I2C通信而ESP32的Wire库需要指定引脚。你需要在代码里调用Wire.begin(21, 22)来初始化I2C而不是用默认的Wire.begin()。这个细节在示例代码里可能没有体现但如果你不指定引脚通信会失败。3.2 MAX30102驱动配置与参数计算MAX30102的配置参数直接影响到测量精度和功耗。我一般用以下配置LED亮度红光和红外都设为0x24约7.2mA。这个值需要根据你的手指厚度和肤色调整。手指厚或者肤色深可以适当调高手指薄或者肤色浅可以调低。亮度太高会饱和太低信噪比不够。采样率100Hz。这个速率足够捕捉脉搏波又不会产生太多数据。如果你要做更精细的波形分析可以调到200Hz或400Hz但功耗会增加。采样平均数4。也就是每4个样本取平均作为一个输出可以平滑噪声。但平均值太大会降低响应速度4是一个比较平衡的值。脉冲宽度411微秒对应18位ADC分辨率。脉冲宽度越大ADC分辨率越高但功耗也越大。411微秒是18位模式下的推荐值。FIFO配置几乎满时触发中断。我们用轮询方式读取所以这个配置影响不大但设置好可以避免数据溢出。这些参数在SparkFun库的示例代码里都有默认值你可以直接抄也可以根据自己的情况微调。我建议先用默认值跑通然后再根据实际读数调整。血氧算法的核心是计算R值公式是R (AC_red / DC_red) / (AC_ir / DC_ir)其中AC是交流分量脉搏搏动引起的信号变化DC是直流分量平均光强。R值和血氧饱和度之间有经验对应关系通常用查表法或者线性拟合来转换。SparkFun的库提供了一个简化的计算方法精度大概在±3%左右对于日常监测够用了。3.3 MLX90614温度读取与校准MLX90614的读取非常简单Adafruit的库提供了readObjectTempC()和readAmbientTempC()两个函数分别读取物体温度和环境温度。物体温度就是我们关心的体温环境温度可以用来做参考。但这里有个问题MLX90614测的是红外辐射温度也就是表面温度。额头表面的温度受环境温度、出汗、风吹等因素影响和核心体温有差异。一般来说额头温度比口腔温度低0.5到1°C比腋下温度低0.3到0.8°C。如果你要用于健康参考最好先用自己的体温计做几次对比找出偏差值然后在代码里做补偿。校准方法在室温稳定、没有阳光直射的环境下用医用体温计测自己的腋下温度同时用MLX90614测额头温度记录差值。重复几次取平均把这个差值加到MLX90614的读数上。我实测下来在室内环境下这个差值大概在0.5°C左右。还有一个细节MLX90614的视场角是90度测量时要注意背景辐射的影响。如果背景是墙壁或者天花板温度比较均匀影响不大。但如果背景有窗户、暖气片、灯光等热源读数会偏高。测量时最好让传感器正对额头背景尽量是均匀的室内环境。4. 完整代码实现与关键逻辑拆解4.1 主程序框架与任务调度ESP32是双核处理器我们可以利用这个特性把不同的任务分配到不同的核心上。比如核心0负责传感器数据采集核心1负责WiFi通信和数据处理。这样即使WiFi通信偶尔阻塞也不会影响传感器采样的实时性。不过对于初学者来说我建议先用单线程轮询的方式跑通然后再考虑用FreeRTOS做多任务。下面是一个典型的单线程主循环结构#include Wire.h #include MAX30105.h #include spo2_algorithm.h #include Adafruit_MLX90614.h MAX30105 particleSensor; Adafruit_MLX90614 mlx Adafruit_MLX90614(); uint32_t irBuffer[100]; uint32_t redBuffer[100]; int32_t spo2; int8_t validSPO2; int32_t heartRate; int8_t validHeartRate; void setup() { Serial.begin(115200); Wire.begin(21, 22); if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) { Serial.println(MAX30102 not found); while (1); } particleSensor.setup(0x24, 4, 2, 100, 411, 4096); if (!mlx.begin()) { Serial.println(MLX90614 not found); while (1); } } void loop() { for (byte i 0; i 100; i) { while (particleSensor.available() false) particleSensor.check(); redBuffer[i] particleSensor.getRed(); irBuffer[i] particleSensor.getIR(); particleSensor.nextSample(); } maxim_heart_rate_and_oxygen_saturation( irBuffer, 100, redBuffer, spo2, validSPO2, heartRate, validHeartRate ); float bodyTemp mlx.readObjectTempC() 0.5; Serial.print(Heart Rate: ); Serial.print(heartRate); Serial.print( bpm, SpO2: ); Serial.print(spo2); Serial.print( %, Temp: ); Serial.print(bodyTemp); Serial.println( C); delay(1000); }这段代码的逻辑是先采集100个样本红光和红外各100个然后调用Maxim官方的血氧算法计算心率和血氧再读取MLX90614的温度最后通过串口输出。采样100个样本在100Hz采样率下需要1秒加上算法计算和温度读取的时间整个循环大概1.2秒左右。4.2 血氧算法实现细节与优化Maxim官方提供的spo2_algorithm.c文件里包含了完整的心率和血氧计算逻辑。这个算法的核心步骤是第一步直流分量提取。对100个红外样本求平均得到DC_ir。对100个红光样本求平均得到DC_red。第二步交流分量提取。对每个样本减去对应的DC值得到AC信号。然后找AC信号的最大值和最小值计算峰峰值。第三步计算R值。R (AC_red / DC_red) / (AC_ir / DC_ir)。第四步查表转换。算法内部有一个R值和血氧饱和度的对应表通过线性插值得到最终的血氧值。这个算法对信号质量有要求。如果手指没有放好、环境光干扰大、或者手指移动了AC信号会失真算出来的血氧值就会跳变。算法里有一个validSPO2标志位用来指示结果是否可信。我在代码里会检查这个标志位如果无效就丢弃这次结果等下一轮。为了提高稳定性我做了两件事一是加了中值滤波连续采集5次结果取中间值输出二是加了运动检测如果AC信号的峰峰值超过某个阈值说明手指在动就丢弃这次数据。这两个措施下来读数稳定性提升非常明显。4.3 温度数据融合与异常值处理MLX90614的读数偶尔会出现异常值比如突然跳到50°C或者降到20°C。这通常是因为传感器受到了瞬态干扰比如有人走过、有风吹过、或者电源波动。处理方法是加一个滑动平均滤波器同时设置合理的上下限。我的做法是维护一个长度为5的环形缓冲区每次读取新温度后先检查是否在30°C到42°C之间。如果超出这个范围就丢弃用上一次的有效值代替。如果在范围内就存入缓冲区然后取缓冲区的中值作为输出。这样既能平滑噪声又能快速响应真实变化。血氧和温度的采样频率不同。血氧算法需要1秒的数据窗口温度可以每100毫秒读一次。我在代码里把温度读取放在血氧采样的间隙里每采集10个血氧样本读一次温度这样两个数据的时间戳基本对齐。5. 数据上传与远程监控实现5.1 WiFi连接与MQTT协议选型ESP32的WiFi功能让远程监控变得非常简单。你可以把数据上传到自己的服务器、云平台、或者直接用手机APP接收。我比较推荐用MQTT协议因为它轻量、实时性好、适合物联网场景。MQTT的基本模型是发布/订阅。ESP32作为客户端把血氧和温度数据发布到一个主题上比如“health/esp32_01/data”。你的手机或者电脑订阅这个主题就能实时收到数据。需要一个MQTT服务器可以自己搭也可以用公共的测试服务器。连接WiFi的代码很简单#include WiFi.h #include PubSubClient.h const char* ssid your_wifi_ssid; const char* password your_wifi_password; const char* mqtt_server your_mqtt_broker_ip; WiFiClient espClient; PubSubClient client(espClient); void setup_wifi() { WiFi.begin(ssid, password); while (WiFi.status() ! WL_CONNECTED) { delay(500); Serial.print(.); } Serial.println(WiFi connected); } void reconnect() { while (!client.connected()) { if (client.connect(ESP32Client)) { // connected } else { delay(5000); } } }这里有个细节ESP32的WiFi和蓝牙可以同时工作但会共享射频资源导致吞吐量下降。如果你同时用蓝牙和WiFi建议把WiFi的省电模式关掉否则延迟会比较大。在代码里调用WiFi.setSleep(false)可以关闭省电模式。5.2 数据格式设计与JSON封装上传的数据最好用JSON格式可读性好扩展方便。一个典型的数据包长这样{ device_id: esp32_01, timestamp: 1234567890, heart_rate: 72, spo2: 98, temperature: 36.5, valid: true }在ESP32端用ArduinoJson库来封装代码大概是这样#include ArduinoJson.h StaticJsonDocument200 doc; doc[device_id] esp32_01; doc[timestamp] millis(); doc[heart_rate] heartRate; doc[spo2] spo2; doc[temperature] bodyTemp; doc[valid] (validSPO2 1); char buffer[200]; serializeJson(doc, buffer); client.publish(health/esp32_01/data, buffer);时间戳这里用的是millis()也就是设备启动后的毫秒数。如果你需要真实时间可以加一个RTC模块或者通过NTP协议从网络获取时间。NTP的代码也不复杂ESP32的例程里有现成的。5.3 手机端接收与可视化方案手机端接收MQTT数据有几个选择。如果你会安卓开发可以用Eclipse Paho的安卓客户端库。如果你不想写代码可以用现成的MQTT客户端APP比如“MQTT Dashboard”或者“IoT MQTT Panel”。这些APP支持订阅主题、解析JSON、显示数值和图表。我用的是“IoT MQTT Panel”配置很简单新建一个连接填入MQTT服务器地址和端口然后添加一个“Text”或者“Gauge”组件绑定到“health/esp32_01/data”主题选择JSON字段“spo2”或者“temperature”。这样手机上就能实时看到数值变化。如果你想要更专业的可视化可以把数据转发到InfluxDB加Grafana。ESP32发布MQTT消息Node-RED或者Telegraf订阅消息并写入InfluxDBGrafana从InfluxDB读取数据并展示趋势图。这套方案稍微复杂一点但功能强大适合做长期监测和数据分析。6. 常见问题排查与实操避坑指南6.1 传感器通信失败排查流程I2C通信失败是最常见的问题。症状是串口打印“MAX30102 not found”或者“MLX90614 not found”。排查步骤我整理了一个速查表现象可能原因排查方法完全找不到设备接线错误检查VIN、GND、SDA、SCL是否接对完全找不到设备电源问题用万用表测模块VIN对GND电压应为3.3V完全找不到设备上拉电阻缺失测SDA和SCL对3.3V的电阻应在10kΩ以内时好时坏接触不良检查杜邦线是否松动换线试试时好时坏总线冲突确认两个模块地址不冲突用I2C扫描程序检查读数异常电源噪声加去耦电容缩短电源线读数异常环境光干扰遮挡传感器避免强光直射I2C扫描程序很简单Arduino IDE里就有示例直接烧进去就能看到总线上有哪些地址。如果扫描不到任何地址说明硬件连接有问题。如果扫描到地址但读数不对说明通信正常但配置或算法有问题。6.2 血氧读数不准的典型原因血氧读数不准我遇到过以下几种情况第一种手指没放好。MAX30102的发光面和接收面之间有隔离墙手指要覆盖住整个窗口不能有缝隙。如果手指太细或者位置偏了部分光线直接反射回接收器没有经过血液吸收导致R值计算错误。解决方法是调整手指位置或者用黑色海绵做一个定位圈。第二种手指压得太紧。压得太紧会阻碍血液循环AC信号幅度变小信噪比下降。正确的手法是轻轻搭上去让传感器刚好接触皮肤不要用力按。第三种环境光太强。日光灯和阳光中的红外成分会直接进入接收器叠加到信号上。解决方法是用不透光的材料遮挡传感器周围或者在暗一点的环境下测量。第四种肤色和指甲油的影响。深色皮肤和指甲油会吸收更多光线导致DC分量偏低R值偏移。这种情况下可以适当调高LED亮度或者换一个手指测量。第五种运动伪影。手指移动会产生低频干扰和脉搏信号混在一起。解决方法是测量时保持手部静止或者在算法里加运动检测。6.3 温度测量偏差的校准技巧MLX90614的读数偏差主要来自两个方面环境温度补偿和发射率设置。环境温度补偿MLX90614内部会根据环境温度对物体温度进行补偿但如果环境温度变化太快补偿可能跟不上。解决方法是让传感器在测量环境中预热几分钟等读数稳定后再采信。发射率设置人体皮肤的发射率大约是0.98MLX90614默认的发射率也是0.98所以一般不需要改。但如果你测的是其他物体比如金属或者玻璃发射率不同读数就会偏差很大。这种情况下需要修改发射率寄存器。测量距离和角度前面说过距离每增加1厘米光斑直径增加约2厘米。如果光斑超出了额头范围就会混入背景温度。测量时保持3到5厘米的距离传感器正对额头中心。还有一个实用技巧连续测量多次取平均。我一般连续读10次去掉最高值和最低值剩下的取平均。这样可以把随机误差降低到±0.2°C以内。6.4 电源管理与续航优化如果你要做便携式设备电源管理就很重要。ESP32在WiFi开启时功耗大概在100mA到200mA之间MAX30102在连续测量时大概10mAMLX90614大概1mA。加起来200mA左右用1000mAh的锂电池大概能撑5小时。要延长续航有几个方向降低采样率。血氧测量不需要一直开着可以每5分钟测一次每次测10秒。这样平均功耗能降到20mA以下续航能到50小时。用深度睡眠模式。ESP32的深度睡眠功耗只有10μA左右。你可以让ESP32定时唤醒测量完就继续睡。用定时器或者外部中断唤醒代码里调用esp_deep_sleep_start()就行。关闭不必要的功能。WiFi和蓝牙不用的时候就关掉串口打印也可以关掉。LED指示灯如果不需要也去掉一个LED就是几个mA。优化LED亮度。MAX30102的LED是功耗大户亮度从0x24降到0x10功耗能降一半但信噪比也会下降。需要根据实际测量效果做权衡。7. 功能扩展与进阶方向7.1 接入米家生态的可行性分析很多人问能不能把这个设备接入米家。技术上可行但需要绕一些弯。米家生态对第三方设备接入有比较严格的限制通常需要通过米家网关或者支持米家的WiFi模组。一种方案是用ESP32模拟米家设备的通信协议。米家设备大多使用miIO协议基于UDP通信。有开源项目实现了miIO协议的ESP32移植可以让ESP32伪装成一个米家设备。但这种做法稳定性一般而且米家APP更新后可能失效。另一种方案是用Home Assistant作为中间层。ESP32通过MQTT把数据发给Home AssistantHome Assistant再通过米家集成把设备虚拟出来。这样米家APP里能看到设备但数据实际来自ESP32。这个方案更稳定但需要额外跑一个Home Assistant服务器。我的建议是如果你只是自己用没必要非得接入米家。用MQTT加手机APP的方案更直接、更可控。如果你确实需要米家生态的联动功能Home Assistant方案是更靠谱的选择。7.2 数据记录与趋势分析长期健康监测的价值在于趋势分析。单次测量的血氧和体温只能反映当时的状态但连续几天的数据能看出变化规律。数据记录可以用SD卡模块ESP32通过SPI接口写CSV文件。每行记录时间戳、心率、血氧、温度。CSV文件可以用Excel打开做简单的图表分析。如果数据量不大也可以存在ESP32的SPIFFS文件系统里。SPIFFS是ESP32内置的闪存文件系统读写速度一般但胜在方便不需要额外硬件。你可以每天生成一个文件文件名用日期方便管理。更专业的做法是把数据上传到InfluxDB用Grafana做可视化。InfluxDB是时序数据库特别适合存储传感器数据。Grafana可以画趋势图、设置报警阈值、生成日报。这套方案我在几个项目里用过稳定性很好。7.3 低功耗设计与电池供电方案如果你要做可穿戴设备低功耗设计是必须的。除了前面说的深度睡眠和降低采样率还有几个技巧选用低功耗的稳压芯片。ESP32开发板上的AMS1117静态电流大概5mA换成HT7333或者MCP1700静态电流能降到几微安。去掉不必要的指示灯和外围电路。USB转串口芯片在电池供电时也在耗电可以用跳线断开。用MOS管控制传感器电源。测量时给传感器供电测完就断电。MAX30102和MLX90614都支持断电重启不需要保持供电。电池选型方面锂电池能量密度高但需要保护电路镍氢电池便宜但体积大。我一般用1000mAh的锂电池加TP4056充电模块整体体积能控制在火柴盒大小。8. 我在这个项目里踩过的坑和最终体会第一个坑是I2C地址冲突。我一开始把MAX30102和MLX90614挂在同一条总线上结果发现MLX90614的地址是0x5AMAX30102是0x57不冲突。但后来加了一个OLED显示屏地址是0x3C也不冲突。真正的问题是总线电容太大通信不稳定。后来缩短了走线加了上拉电阻问题解决。第二个坑是血氧算法的输入数据格式。Maxim的算法要求输入是uint32_t数组但我一开始用了int数组结果算出来的血氧值全是乱的。后来查了库的源码才发现这个问题。这种细节在文档里往往不会写只能自己踩坑。第三个坑是温度补偿。我一开始直接用MLX90614的读数发现比体温计低了一度多。后来查资料才知道额头温度和核心体温有差异需要加补偿值。补偿值不是固定的跟环境温度有关冬天和夏天不一样。我最后是用一个简单的线性拟合根据环境温度动态调整补偿值。第四个坑是WiFi和传感器采样的冲突。开启WiFi后串口打印会偶尔卡顿导致采样间隔不均匀。后来我把传感器采样放在核心0WiFi通信放在核心1用FreeRTOS的任务通知机制同步数据问题才解决。这个项目从最初的想法到最终稳定运行大概花了两个周末。硬件成本不到一百块但学到的东西远超这个价值。如果你也想做一个我的建议是先把传感器调通再加WiFi最后做结构。每一步都验证好了再往下走不要想着一次把所有功能都加上。遇到问题先查数据手册再搜社区最后自己动手测。大部分问题都有现成的答案关键是你要知道怎么找到它。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门