1. 项目概述从零构建一个可穿戴心率监测器心率监测听起来像是专业医疗设备才有的功能但如果你手头有一块像XIAO nRF52840这样的低功耗蓝牙微控制器再搭配一个合适的生物医学传感器自己动手做一个其实并不遥远。这个项目就是一次将嵌入式系统开发与生物医学信号处理相结合的实践目标是打造一个可以佩戴在身上的、能够实时显示心率状态的可穿戴设备。整个过程涉及硬件选型、电路设计、信号处理、固件编程以及外壳制作算是一个比较完整的微型产品开发流程。我这次使用的核心是Seeed Studio出品的XIAO nRF52840开发板它最大的特点就是“小”和“省电”。尺寸只有21mm x 17.5mm比一枚硬币大不了多少但内部搭载了Nordic的nRF52840芯片这是一颗ARM Cortex-M4内核的处理器性能足够处理实时信号并且原生支持蓝牙5.0。对于需要长时间佩戴、依赖电池供电的设备来说它的超低功耗特性深度睡眠时电流仅5uA简直是福音。另一个关键部件是Bitalino生物医学传感器套件中的ECG心电图模块。Bitalino本身是一个开源的生物信号采集平台它的ECG模块已经为我们做好了信号放大和初步滤波让我们可以更专注于应用逻辑而不是从头开始设计模拟前端电路。整个系统的思路很直观通过贴在胸部的三个电极采集微弱的体表心电信号经过Bitalino ECG模块的调理后将模拟信号送入XIAO nRF52840的ADC模数转换器引脚。微控制器内部的程序会实时分析这个数字信号波形识别出代表心跳的R波峰值从而计算出瞬时心率和心率变异性等信息。最后处理结果一方面可以通过蓝牙发送到手机App进行记录和查看另一方面也能直接驱动一组LED灯用灯光闪烁的节奏来直观反映心跳实现一个脱离手机的、纯粹的“光效”心率指示器。下面我就把从电路焊接、编程调试到外壳装配的每一步拆开详细说说其中的门道和踩过的坑。2. 核心硬件选型与设计思路解析2.1 为什么选择XIAO nRF52840与Bitalino组合在做健康监测类项目时硬件选型直接决定了项目的可行性、功耗和最终体积。我选择XIAO nRF52840和Bitalino ECG模块的组合是基于几个非常实际的考量。首先看主控。市面上常见的Arduino Uno或NodeMCU虽然入门简单但体积大、功耗高根本不适合做可穿戴设备。而一些更小的板子比如ATtiny系列性能又可能不足以处理实时的信号分析。XIAO nRF52840在这中间找到了一个完美的平衡点。它的nRF52840芯片内置了浮点运算单元FPU这对于处理ECG信号这类需要滤波和数学运算的任务非常有帮助比用软件模拟浮点运算要快得多、也省电得多。蓝牙5.0的支持意味着我们可以轻松地将数据流式传输到手机进行更复杂的显示或云端记录而板载的电池充电管理电路让我们可以直接连接一颗3.7V的锂聚合物电池省去了外接充电模块的麻烦和空间。其次是传感器。直接使用裸电极和自制放大电路来采集ECG信号是一个门槛极高且极易引入噪声的“深坑”。心电信号非常微弱毫伏级别且极易受到工频干扰50/60Hz和肌电干扰。Bitalino的ECG模块如BITalino (r)evolution ECG实际上是一个高度集成的前端它内部包含了仪表放大器、带通滤波器和右腿驱动电路。仪表放大器能极大地抑制共模噪声比如来自电源的干扰带通滤波器通常设为0.5Hz到40Hz左右则能有效滤除基线漂移和高频肌电噪声只留下我们关心的QRS波群包含R波频段。这相当于把最棘手、最专业的模拟电路问题打包解决了我们拿到手的已经是一个比较“干净”的、幅值在0-3.3V范围内的模拟信号可以直接送给微控制器的ADC去读取。注意Bitalino模块通常输出的是单端信号其参考电压REF引脚需要妥善处理。常见的接法是将其通过一个电阻分压网络例如两个10kΩ电阻连接到VCC和GND之间取中点电压1.65V作为偏置这样信号就能在ADC的量程范围内正负摆动。如果REF直接接地负向的信号部分就会被削波导致波形失真。2.2 系统架构与信号流设计整个系统的架构可以清晰地分为传感层、处理层和指示层。传感层就是贴在身上的三个电极RA右臂、LA左臂、RL右腿和Bitalino ECG模块。处理层是XIAO nRF52840它负责ADC采样、数字信号处理和心率计算。指示层则包括了一组LED灯和可选的蓝牙无线传输。信号流的细节值得深入说说。ECG模块的输出线连接到XIAO的某个ADC引脚例如A0/D1。XIAO nRF52840的ADC分辨率是12位参考电压为3.3V这意味着它可以将0-3.3V的电压量化为0到4095的数值。对于心电信号我们更关心的是波形的相对变化和节律而不是绝对电压值所以12位分辨率提供的动态范围完全足够。在程序里我们需要设置一个合适的采样率。根据奈奎斯特采样定理要无失真地还原信号采样率至少需要是信号最高频率的两倍。心电信号的有效成分主要在0.5-40Hz所以理论上采样率大于80Hz即可。但在实践中为了更精确地定位R波峰值我们通常需要更高的采样率一般设置在200Hz到500Hz之间。XIAO nRF52840的M4内核完全能胜任这个速率的实时采样和计算。处理的核心算法是QRS波检测。一个简单但有效的方法是设置一个动态阈值。程序会持续监测ADC读数的变化当发现信号值在短时间内快速上升并超过阈值时就认为检测到了一个R波峰值。记录下两个峰值之间的时间间隔RR间期用60除以这个间隔单位秒就得到了瞬时心率单位次/分钟。为了防止噪声引起的误触发通常还会加入一个“不应期”设置即在检测到一个R波后的200-300毫秒内暂停检测因为生理上不可能在这么短的时间内出现两次心跳。3. 电路设计与PCB制作实操要点3.1 从原理图到万用板布局有了核心模块我们需要搭建一个最小系统电路将XIAO、ECG模块、LED指示灯和电源连接起来。虽然最终用了万用板洞洞板但先在纸上或EDA软件里画个简单的原理图是非常必要的它能帮你理清连接关系避免焊接时抓瞎。我的连接方案如下电源部分一颗3.7V/500mAh的锂聚合物电池正负极分别接到XIAO nRF52840的“BAT”和“GND”引脚。注意XIAO的USB口和BAT引脚是连通的并且板上有充电管理芯片所以直接接电池是最简洁的方案。整个系统的3.3V电源都从XIAO的“3V3”引脚取电。ECG模块连接VCC- XIAO的3V3GND- XIAO的GNDOUT(信号输出) - XIAO的A0/D1(ADC输入引脚)REF(参考电压) - 通过一个由两个10kΩ电阻串联的分压网络的中点连接。即3V3- 10kΩ电阻 -REF引脚 - 10kΩ电阻 -GND。这样REF点的电压就是1.65V。LED阵列连接我用了5个白色LED来模拟心跳闪烁。每个LED的阳极通过一个限流电阻我后来去掉了但建议新手保留例如220Ω分别连接到XIAO的数字IO口如D5, D6, D7, D8, D9。所有LED的阴极连接在一起接至GND。这样可以通过程序依次点亮LED形成“流动”的视觉效果。在万用板上布局时我的原则是“功能分区走线最短”。我把XIAO的母座放在板子中央电源接口和电池线放在一侧ECG模块的接口放在靠近ADC引脚的另一侧LED阵列则布置在板子边缘方便光线透出。对于数字和模拟部分虽然没有做严格的隔离但尽量让ECG的信号线远离LED的驱动线以减少开关噪声对微弱模拟信号的干扰。3.2 焊接、组装与调试中的“坑”焊接过程本身是基本功但有几个细节决定了成败。首先一定要先焊接电阻、母座这类高度较低的元件最后再焊接ECG模块这种有排针或体积较大的元件。我一开始先焊了ECG模块结果在焊接旁边的小电阻时烙铁头非常容易碰到模块的塑料外壳甚至可能导致引脚短路。其次给XIAO使用母座排母而不是直接焊死在板子上是一个明智的选择。这不仅仅是为了复用更重要的是便于调试。在开发阶段你可能会频繁地拔插USB线来下载程序和监控串口输出直接焊接会使得这些操作非常困难也增加了损坏板子的风险。实操心得焊接多引脚排母时可以先将其插在XIAO开发板上然后将这个“组合体”一起放到万用板上焊接。这样能确保排母与板子绝对垂直并且引脚位置分毫不差。焊好一排针脚后再轻轻取下XIAO即可。焊接完成后万用表是你最好的朋友。在上电前必须做以下检查电源短路测试用蜂鸣档测量电池正负极接入点之间的电阻确保没有直接短路。电压测试接上电池测量XIAO的3V3引脚对地电压确认是稳定的3.3V左右。信号通路测试测量ECG模块REF引脚的电压确认是否为1.65V一半的3.3V。我遇到的一个真实问题是LED不亮。检查后发现我在布局时为了整齐将LED的阴极都接到了一条公共的铜箔走线上但这根走线在某个过孔处因为焊接不良而断裂了导致所有LED阴极悬空。用万用表蜂鸣档沿着走线一点点测才找到这个断点。所以焊接完一定要仔细检查每一根你认为连接了的走线特别是那些长的、拐弯多的。另一个教训是关于机械强度的。万用板本身比较脆在固定到外壳或进行组装时如果受力不均或者被挤压很容易从焊盘处断裂。我的第一版板子就是在用台钳固定准备打孔时因为用力稍大直接裂成了两半。所以对于需要承受一定机械应力的项目要么选择更厚实的玻纤板要么在布局时避免在受力点附近放置重要线路或者考虑用3D打印一个支撑结构来分担压力。4. 固件编程信号采集与心率算法实现4.1 开发环境搭建与基础配置为XIAO nRF52840编程最方便的方法是使用Arduino IDE并添加Seeed Studio的板卡支持。首先在Arduino IDE的“文件-首选项-附加开发板管理器网址”中添加以下网址https://files.seeedstudio.com/arduino/package_seeeduino_boards_index.json。然后在“工具-开发板-开发板管理器”中搜索“Seeed nRF52”安装“Seeed nRF52 Boards”这个包。安装完成后就可以在开发板列表中选择“Seeed XIAO nRF52840 (Sense)”了。选择正确的端口后还需要配置两个重要的选项Bootloader选择Seeed UF2Port选择对应的串口。UF2是一种很方便的拖放式烧录协议但在进行深度调试时我更喜欢使用J-Link (via CMSIS-DAP)作为调试器这可以通过选择Bootloader为CMSIS-DAP来实现它能提供单步调试等更强大的功能。程序的第一步是包含必要的库和定义引脚。除了基本的Arduino.h我们还需要analogRead函数来读取ADC以及可能用到的数学库。// 引脚定义 const int ecgPin A0; // ECG信号输入引脚对应D1 const int ledPins[] {5, 6, 7, 8, 9}; // LED连接的引脚数组 const int numLeds 5; // 心率计算相关变量 int sensorValue 0; unsigned long lastHeartbeatTime 0; unsigned long heartbeatInterval 0; int bpm 0; bool pulseDetected false; // 信号处理变量 const int sampleRate 250; // 采样率250 Hz const int sampleInterval 1000000 / sampleRate; // 以微秒计的采样间隔 unsigned long lastSampleTime 0; // 阈值与滤波 int threshold 512; // 初始阈值ADC量程中点附近 int signalMax 0; int signalMin 1023; const int noiseFloor 10; // 噪声阈值4.2 核心心率检测算法剖析心率检测的核心在于从连续的、带有噪声的ECG信号中可靠地识别出R波峰值。我采用了一个简化但鲁棒性不错的“阈值自适应”算法。这个算法不依赖于复杂的数字滤波器如带通或陷波而是通过跟踪信号的局部最大值和最小值来动态调整触发阈值。在主循环loop()中我们以固定的时间间隔由sampleRate决定读取ADC值。为了消除工频干扰一个简单的方法是计算连续几个采样点的移动平均值。这里我用了4个点的平均void loop() { unsigned long currentMicros micros(); // 固定间隔采样 if (currentMicros - lastSampleTime sampleInterval) { lastSampleTime currentMicros; // 读取ADC并做简单平滑 int rawValue analogRead(ecgPin); sensorValue (3 * sensorValue rawValue) 2; // 一阶低通滤波近似于移动平均 // 动态更新信号的最大最小值 if (sensorValue signalMax) { signalMax sensorValue; } if (sensorValue signalMin) { signalMin sensorValue; } // 每200个采样点约0.8秒重置一次最大最小值实现滑动窗口 static int sampleCount 0; sampleCount; if (sampleCount 200) { sampleCount 0; // 根据过去窗口内的峰峰值动态计算阈值。阈值设为信号幅值峰峰值的60%加上最小值。 int amplitude signalMax - signalMin; if (amplitude noiseFloor) { // 避免在无信号或低信号时误触发 threshold signalMin (amplitude * 6 / 10); // 阈值为最小值 幅值的60% } signalMax 0; signalMin 1023; } // 心率检测逻辑 if (sensorValue threshold !pulseDetected) { pulseDetected true; unsigned long currentTime millis(); if (lastHeartbeatTime 0) { heartbeatInterval currentTime - lastHeartbeatTime; bpm 60000 / heartbeatInterval; // 计算BPM // 限制心率在合理范围内例如30-200 BPM if (bpm 30) bpm 30; if (bpm 200) bpm 200; } lastHeartbeatTime currentTime; // 触发LED效果 animateLeds(); } // 在检测到峰值后设置一个“不应期”防止同一个R波被多次检测 if (pulseDetected sensorValue threshold) { pulseDetected false; } } }animateLeds()函数控制LED的动画效果。最简单的实现是让所有LED随心跳同步闪烁。但为了更直观我实现了一个“流水灯”效果让灯光像波浪一样从一端流向另一端其速度可以与心率挂钩心率快则流水快。void animateLeds() { // 先全部熄灭 for (int i 0; i numLeds; i) { digitalWrite(ledPins[i], LOW); } // 实现流水效果 for (int i 0; i numLeds; i) { digitalWrite(ledPins[i], HIGH); delay(50); // 每个LED点亮间隔可根据bpm调整 digitalWrite(ledPins[i], LOW); } }这个算法在信号质量较好时工作得很稳定。它的优势是计算量小非常适合在资源有限的微控制器上运行。但它对基线漂移和大的运动伪影比较敏感。在实际佩戴中如果电极接触不良或人体移动信号可能会剧烈变化导致阈值计算失常。4.3 蓝牙数据传输与手机端显示可选进阶如果想让数据在手机上可视化或存储蓝牙功能就派上用场了。XIAO nRF52840支持蓝牙低功耗BLE我们可以将心率BPM和原始的ECG波形数据作为一个特征值Characteristic广播出去。这里需要使用ArduinoBLE库。首先在setup()中初始化BLE创建一个服务Service和一个特征值。特征值需要设置可读READ和可通知NOTIFY属性这样手机端在订阅后每当心率更新设备就会自动推送新值。#include ArduinoBLE.h BLEService heartRateService(180D); // 标准心率服务UUID BLEUnsignedCharCharacteristic bpmCharacteristic(2A37, BLERead | BLENotify); // 标准心率测量特征 void setup() { // ... 其他初始化代码 if (!BLE.begin()) { // 蓝牙初始化失败处理 } BLE.setLocalName(XIAO_HR_Monitor); BLE.setAdvertisedService(heartRateService); heartRateService.addCharacteristic(bpmCharacteristic); BLE.addService(heartRateService); bpmCharacteristic.writeValue(0); // 初始值 BLE.advertise(); } void loop() { // ... 原有的采样和计算代码 // 当计算出新的bpm后更新BLE特征值 static int lastReportedBpm 0; if (abs(bpm - lastReportedBpm) 1) { // 避免频繁发送微小变化 bpmCharacteristic.writeValue(bpm); lastReportedBpm bpm; } BLE.poll(); // 处理BLE事件 }在手机端可以使用像LightBlue这样的通用BLE调试App来查看数据或者自己用MIT App Inventor、React Native等工具开发一个简单的应用来接收并绘制心率曲线。通过BLE这个可穿戴设备就从单纯的视觉指示器升级为了一个真正的无线健康数据采集终端。5. 机械结构设计与3D打印装配5.1 外壳设计功能性与佩戴体验的平衡对于可穿戴设备外壳设计至关重要它需要保护内部电路提供舒适的佩戴感并方便用户操作。我的设计分为三个部分主壳体、LED灯罩和胸部电极固定带。使用Fusion 360进行设计。主壳体是一个扁平的盒子内部有支撑柱和卡槽用于固定万用板、电池和XIAO开发板。设计时要特别注意以下几点尺寸精确用卡尺精确测量万用板和电池的外形尺寸并在建模时留出至少0.5mm的装配间隙。太紧会装不进去太松则设备会在壳体内晃动。开孔设计USB接口为XIAO的Type-C接口开一个足够大的方孔方便充电和调试。LED窗口在主壳体正面开一排与LED位置对应的小孔或者设计一个独立的、半透明的灯罩部件通过散射让灯光更柔和均匀。我选择了后者用白色PLA打印灯罩透光效果很好。电极线出口在壳体侧面设计一个小孔让ECG模块的电极线能够穿出。散热虽然功耗很低但仍在底部设计一些细小的通风孔。固定方式我采用了最简单的上下盖卡扣配合。在设计卡扣时悬臂梁的厚度和钩子的角度需要仔细调整打印后可能需要用小刀稍微修整才能达到合适的松紧度。也可以设计螺丝柱用M2的小螺丝固定这样更可靠但组装稍麻烦。胸部电极固定带的设计目标是舒适和稳定。我设计了一个扁平的、弧形的塑料片中间有一个孔用于穿过三根电极线。塑料片的两端留有槽口用于固定弹力织带。织带的长度可调以适应不同的胸围。5.2 打印与后处理实战经验打印材料选择PLA因为它容易打印、无异味且成本低。打印参数设置上层高我选用0.2mm以获得较好的表面质量填充率设为20%以兼顾强度和重量。对于主壳体这类需要承重和卡扣功能的部件打印方向很重要。务必让卡扣的钩子部分在打印时是“站立”的而不是平躺的。平躺打印时卡扣的钩子部分会是悬空打印强度极差很容易断裂。而站立打印每一层都是完整的轮廓强度高得多。重要提示在切片软件如Creality Slicer或Cura中务必为模型添加“支撑Support”。外壳内部的支撑柱、卡扣的悬空部分都需要支撑材料。我最初尝试不加支撑打印卡扣结果悬空部分拉丝严重形状一塌糊涂根本无法使用。支撑材料虽然会增加打印时间和后处理工作量但对于保证复杂结构的成型质量是必须的。打印完成后需要小心地去除支撑材料。使用扁口钳或镊子一点点剥离对于内部难以触及的支撑可以用小刀或专用的支撑去除工具。去除支撑后用细砂纸例如400目、800目轻轻打磨结合面的毛刺和粗糙处特别是上下盖的接触边缘确保能平整闭合。组装时我使用了401或496瞬干胶俗称“快干胶”来粘合PLA部件。在粘合前先用酒精棉片清洁粘合面去除油脂和灰尘。涂抹胶水要少量、均匀对准位置后按压30秒左右即可初步固定。切记保持通风并避免胶水接触皮肤或眼睛。对于电极线出口和电池线等位置为了防止长期弯折导致线材断裂需要进行“应力消除”。理想情况下应该使用热缩管但我手头没有合适直径的就用了热熔胶在出口处打了一个“应变释放结”将线材固定住避免内部焊点受力。虽然不如热缩管美观但效果一样可靠。6. 系统集成测试与问题深度排查6.1 上电测试与功能验证流程所有硬件焊接完毕、外壳组装完成后不要急于佩戴必须进行系统的上电测试。第一步静态功耗测试。不接ECG电极将设备开机用万用表的电流档串联在电池回路中测量整机工作电流。XIAO nRF52840在运行上述心率检测程序、LED熄灭时电流大约在5-10mA左右。当LED被点亮时电流会有明显上升每个LED约5-20mA取决于限流电阻和亮度。这个测试可以帮你估算电池续航。一颗500mAh的电池如果平均电流10mA理论续航约50小时。进入深度睡眠模式可以进一步省电但本项目需要实时监测所以常开是合理的。第二步信号模拟测试。在没有真人测试前可以用一个简单的信号源来验证整个信号链是否工作。找一个函数发生器或者用另一个Arduino模拟DAC输出产生一个频率在1-2Hz模拟60-120 BPM、幅值在1-2V峰峰值、偏置在1.65V的正弦波或方波连接到ECG模块的信号输入点注意共地。观察LED是否能够以相应的频率闪烁同时通过Arduino IDE的串口绘图器Serial Plotter查看ADC读取的波形是否正常。这个步骤能快速排除硬件连接和基础软件逻辑的错误。第三步真人静态测试。清洁皮肤用酒精棉片擦拭可以减少接触电阻贴好电极右锁骨下、左锁骨下、左下胸部连接设备。保持静止观察LED闪烁是否规律同时通过串口监视器输出实时的心率数值和波形图。一个正常的ECG波形应该能清晰看到P波、QRS波群和T波虽然我们的算法只关注R波。串口绘图器里应该看到规律的尖峰。6.2 典型问题、根源分析与解决方案在实际测试中你几乎一定会遇到下面这些问题。这里我把它们、可能的原因和解决办法整理成表方便快速排查问题现象可能原因分析排查步骤与解决方案LED完全不亮1. 电源未接通或电池没电。2. LED公共阴极/阳极连接断路。3. 程序未正确配置IO口模式应设为OUTPUT。4. 限流电阻过大或LED极性接反。1. 用万用表测电池电压、XIAO的3V3引脚电压。2. 用万用表蜂鸣档检查LED电路通路。3. 检查setup()中是否有pinMode(ledPin, OUTPUT)语句。4. 短路限流电阻测试或检查LED长脚阳极是否接对了正极。LED常亮不闪烁1. 心率检测算法失效pulseDetected标志位一直为true。2. 阈值threshold设置过低导致信号持续高于阈值。3. ECG信号输入持续为高电平如REF引脚接错。1. 通过串口打印sensorValue和threshold观察数值。2. 检查REF引脚电压是否为1.65V左右。3. 检查算法中“不应期”逻辑和阈值重置逻辑是否正确。心率读数极快且不稳定如200 BPM1.最常见原因电极接触不良或脱落导致信号充满高频噪声算法将噪声峰值误判为R波。2. 肌电干扰肌肉紧张、身体移动。3. 工频干扰50Hz严重。1.重新粘贴电极确保与皮肤接触良好。可在电极片上涂抹少量导电膏。2. 保持测试者静止、放松。3. 在软件中增加一个简单的50Hz陷波滤波器或检查设备是否远离强交流电源。心率读数极慢或为零1. 信号太弱R波峰值未超过阈值。2. ECG模块增益不足或损坏。3. 电极位置贴错参考标准I导联位置。1. 通过串口绘图器观察原始波形看QRS波群幅值是否明显通常应有数百个ADC单位的变化。2. 尝试交换RA和LA电极位置。3. 确保ECG模块供电正常。蓝牙无法连接或数据不更新1. 手机蓝牙未打开或权限未授予。2. XIAO的BLE未成功初始化或开始广播。3. 手机App与服务/特征UUID不匹配。4. 程序卡死未执行BLE.poll()。1. 用nRF Connect等BLE扫描工具查看是否能发现“XIAO_HR_Monitor”设备。2. 检查setup()中BLE初始化部分的返回值。3. 确认手机App订阅的特征UUID与代码中一致。4. 确保loop()中定期调用BLE.poll()。设备发热严重1. 电源短路。2. LED驱动电流过大未加限流电阻或电阻值太小。3. 微控制器持续高频运行。1. 立即断电用万用表检查短路点。2. 测量LED点亮时流过的电流计算公式I (3.3V - LED压降) / 电阻。白色LED压降约3.0V若用220Ω电阻电流约(3.3-3.0)/220≈1.4mA是安全的。若无电阻电流可能很大。3. 检查程序是否有死循环。关于我更换LED的教训最初我使用了红色LED搭配220Ω电阻但在环境光稍亮时灯光效果非常不明显。后来我换成了白色LED由于其本身更亮我去掉了限流电阻以增加亮度。这是一个有风险的操作因为IO口的最大拉电流能力是有限的通常每个引脚约20mA所有引脚总和有限制。直接驱动白色LED可能导致电流超标长期可能损坏IO口。更安全的做法是保留一个较小阻值的电阻如10Ω-100Ω或者使用晶体管来驱动LED。我的做法是在评估了闪烁占空比很低每次点亮时间很短后的一种权衡不推荐初学者模仿。6.3 优化与改进方向这个项目作为一个原型已经可以工作但还有很大的优化空间算法优化引入更专业的数字滤波器如巴特沃斯带通滤波器来进一步抑制噪声。可以使用开源的心率检测算法库如Pan-Tompkins算法它能更稳健地在噪声中检测QRS波。功耗优化当前LED是全亮驱动功耗大户。可以改用PWM调光降低亮度。在未检测到心跳一段时间后让系统进入轻度睡眠仅ADC定时唤醒采样可以大幅延长续航。佩戴优化目前的胸部固定带可能不适合长时间运动佩戴。可以考虑改用更柔软、透气的医用级硅胶或织物材料设计成类似心率胸带的样式。数据可视化开发一个简单的手机App不仅能显示实时心率还能绘制心电图波形计算心率变异性HRV并具备历史数据记录和导出功能。无线充电为外壳集成一个Qi无线充电接收线圈实现无接触充电提升产品的完整度和用户体验。这个基于XIAO nRF52840和Bitalino的心率监测系统项目从芯片选型到外壳打印完整地走了一遍嵌入式可穿戴产品的开发流程。它最宝贵的价值不在于做出了一个多么精密的医疗设备而在于亲身实践了如何将生物电信号这种微弱的模拟量通过硬件调理、数字采样、软件算法最终转化为直观可读的信息。过程中遇到的每一个问题从焊接断裂到信号干扰从算法调试到结构设计都是极其宝贵的经验。当你看到LED灯随着自己的心跳规律闪烁时那种连接了硬件与生命的成就感正是嵌入式开发与生物医学工程交叉魅力的最佳体现。