MCU Sensor Hub架构在电子血压计中的设计与实现
做嵌入式医疗设备这些年我接触过不少血压测量方案从早期的分立式模拟电路到后来带MCU的数字方案再到现在的MCU Sensor Hub架构变化确实大。简单说MCU Sensor Hub就是把压力传感器、加速度计、温度传感器这些数据全部汇聚到一颗MCU上由它统一完成采集、滤波、特征提取和血压计算既当传感器中枢又当算法主脑。这套方案解决了传统方案电路分散、校准困难、实时性差的问题非常适合做电子血压计、可穿戴健康设备这类产品。无论你是刚入行的嵌入式工程师还是想把成熟方案快速落地的产品经理这篇内容都能给你一个完整的参考。1. 方案整体设计与架构思路1.1 为什么不是分立器件而要用MCU做Sensor Hub早年做血压计模拟电路时代是压力传感器、运放、窗口比较器、屏显驱动一堆IC凑在一起每个功能模块独立调参非常痛苦。后来进入数字时代最简单的是MCU只负责采集数据、计算、显示传感器各自带调理芯片通过I2C或SPI上报。这个方案能用但有个致命问题多路传感器并行接入时数据同步、优先级、休眠唤醒的协调非常麻烦一旦出现干扰或者某一路传感器异常整个系统没有任何弹性缓冲。MCU Sensor Hub的核心思路是把MCU放在传感器和上层决策逻辑中间所有传感器数据先经过MCU做一次预处理和融合再把高质量的数据交给上层。这样带来的好处很明显实时性好。充气泵、泄气阀、压力采样这三件事必须严格同步MCU直接管底层的PWM和ADC数据从传感器到计算核心的延迟可以控制在微秒级。功耗可控。Sensor Hub架构下MCU可以采用轮询加中断的混合模式没有测量任务时外设全部关断MCU进入低功耗睡眠按一个按键就能唤醒整个链路。算法可迁移。血压计算、滤波、运动伪差识别这些算法写在MCU内部换一个蓝牙SoC或者升级显示模块核心算法不用变。扩展性好。今天接血压传感器明天想接血氧探头、体温探头Sensor Hub的架构不需要推翻重来新模块挂到总线上加一段驱动和状态机就行。所以我在做方案评审时基本都会要求用MCU Sensor Hub架构除非产品实在简单到只剩一个传感器。站在产品迭代的角度这个架构的投资回报率是最高的因为你不需要为下一代产品重写底层。1.2 系统总体架构与数据流设计整个血压测量方案数据流大概是这样的袖带里的气压经压力传感器转换为模拟电压或数字码值进入MCU后先做校准补偿再做带通滤波提取脉搏波与此同时MCU还要通过PWM控制充气泵和泄气阀。经过多次心跳周期MCU从脉搏波包络中找出最大振荡点计算平均压再按比例关系算出收缩压和舒张压最后把结果送到LCD屏、蓝牙或手机App。从硬件模块划分主要有感知层、处理层、执行层和交互层感知层压力传感器、加速度计运动检测、温度传感器。压力传感器多数是模拟输出也可以选择带I2C的数字压力传感器后者能省掉外部运放。处理层一颗带ADC、定时器、PWM和低功耗模式的MCU这是Sensor Hub的核心。执行层充气泵直流电机或微型气泵、泄气阀比例阀或电磁阀通过MOS管或驱动芯片受MCU控制。交互层LCD段码屏或LCD点阵屏以及BLE模块。在实际项目中为了控制成本很多人倾向用单颗MCU直接驱动BLE而不是MCU加蓝牙双颗芯片。比如带BLE的ARM Cortex-M4芯片把Sensor Hub功能和无线协议栈放在同一颗芯片里虽然协议栈会占用部分资源但整机BOM成本和PCB面积都下降明显。如果是可穿戴血压手表建议用带BLE的SoC方案如果是家用上臂式电子血压计MCU外接蓝牙模块也完全够用。我在这里给一个芯片选型的参考表格都是实际项目中比较常见的组合方案类型典型芯片适合场景关键优势主要代价裸机MCU外部蓝牙模块STM32F0xx nRF52832家用上臂式血压计稳定、开发简单、成本低BOM器件多PCB面积大单芯片SoC带BLETLSR8258、nRF52840可穿戴血压手表集成度高、功耗低需处理协议栈资源占用高性能工业MCUSTM32H7、TI AM261x高端多传感医疗终端异构并行处理能力很强成本偏高开发复杂度大再补充一点关于高端MCU的使用场景。现在有不少大厂在工业医疗领域推高性能MCU比如TI AM261x这类异构计算、实时控制和工业通信一体的架构或者STM32H7系列里专门做FOC电机控制的高性能MCU。这些芯片用在血压计上确实性能过剩但如果产品希望在同一颗MCU上同时做无线充电控制、多路传感器融合、FOC驱动的气泵电机那高端MCU就派上用场。我们在做一款带无线充电的医疗健康终端时就用过类似方案电机控制环和传感器采样环在不同的执行内核上独立运行互不干扰。2. 核心传感器与信号处理细节2.1 压力传感器选型与采样配置压力传感器是决定测量精度的第一个关卡。袖带测量范围一般要覆盖到300mmHg加上安全裕量建议传感器量程选0到37kPa甚至更高。选择传感器有三个要点表压还是绝对压。血压测量要的是袖带内相对环境气压的压力所以通常选表压传感器。如果用了绝对压传感器需要在软件里减去环境气压不仅多一个变量还会引入气压计误差不推荐。模拟输出还是数字输出。模拟输出的好处是响应快、可选传感器多但MCU需要集成高精度ADC对采样电路、基准电压和布线都更挑剔。数字接口的传感器如I2C接口的SSC系列、BMP388自带内部温度补偿和校准软件更省事但采样率一般不会太高选型时要仔细看datasheet里的OSR设置别让采样率拖了后端算法的后腿。温漂。如果产品要在零下20度到50度环境使用压力传感器的温漂补偿必须考虑。选择带温度补偿输出的传感器或者在PCB上放一颗温度传感器软件做分段补偿否则冬天和夏天的测量结果可能差好几个mmHg。采样率方面示波法脉搏波频率大概在1到4Hz但包络提取和峰值检测需要足够的过采样。我一般把压力采样率设在200Hz对应5ms一个点。这样既能保证包络细节也不会给MCU造成太大负担。ADC分辨率我用16位实际测量中压力范围0到300mmHg用满量程算下来每一个可判别的码值对应的压力变化大约0.005mmHg处理微小振荡波时余量充足。2.2 示波法血压计算原理拆解市面上电子血压计绝大多数用的是示波法原理可以这样理解袖带充气到超过收缩压把动脉压闭然后以恒定速率放气。在放气过程中心脏每次泵血都会在袖带里产生一个很小的压力振荡这个振荡叠加在袖带基础压力上。MCU的任务就是把两路信号分离开直流分量是袖带压力交流分量是脉搏波。计算流程分几步走。第一步从原始压力数据中提取袖带压力序列第二步通过带通滤波得到脉搏波振荡包络第三步找到振荡幅度最大的位置此时袖带压力等于平均动脉压MAP第四步按照收缩压和舒张压的经验比例从包络的左右两侧分别找到对应幅度点。具体来说收缩压位置通常在最大振荡幅度的50%左右舒张压在75%左右但不同算法厂商会根据自己的临床数据库调整这些比例。比如有些算法会在0.45到0.55之间动态调整有些会结合人群特征年龄、臂围做修正。这个比例参数强烈建议用自家的临床测试数据来标定不要直接照搬别人的库参数否则在不同人群上测出来的偏差会很明显。这里要特别提醒一点示波法不是直接测量血压而是通过振荡包络特征推算血压所以它依赖一个假设——脉搏波振荡从被阻断到恢复的过渡过程中包络形状是光滑的单峰曲线。如果测量过程中出现明显体动包络会变形计算出的血压值就会失真。这也是为什么Sensor Hub方案里一定要加加速度计靠它来识别运动伪差一旦检测到手臂抖动直接丢弃当前测量周期。2.3 MCU端的滤波器设计与实现压力传感器输出的原始信号里直流袖带压可能高达200mmHg而脉搏波振荡通常只有几个mmHg二者的幅度差了两个数量级。如果直接用ADC原始码值做峰值检测微弱振荡会被直流量淹没。所以软件滤波是整个方案里非常关键的一环。我的做法是先用一个一阶高通或带通滤波器把直流分量去掉再用滑动平均做去噪处理。工程上我会维护一个环形缓冲区每次ADC中断到来往里塞一个原始压力值然后跑一次IIR滤波。IIR的系数不需要特别复杂二阶巴特沃斯带通就够了。// 带通滤波器示例采样率200Hz通带0.5~10Hz // 这里以二阶IIR为例实际系数通过滤波器工具生成 float iir_bp(float x, float* x_hist, float* y_hist, const float* b, const float* a) { float y b[0] * x b[1] * x_hist[0] b[2] * x_hist[1] - a[1] * y_hist[0] - a[2] * y_hist[1]; x_hist[1] x_hist[0]; x_hist[0] x; y_hist[1] y_hist[0]; y_hist[0] y; return y; }实际工程里我不建议在MCU里用太高阶的滤波器阶数越高群延迟越大脉搏波的峰值位置会被拉偏MAP定位就不准。用二阶或四阶巴特沃斯就足够了。如果MCU资源够可以在放气过程结束后对完整波形做一次离线滤波如果MCU性能弱就做在线滑窗滤波。滤波器实现时还要注意定点数的问题。很多MCU没有FPU直接用浮点库会很慢可以把滤波器系数缩放并转成Q15或Q31格式用定点运算代替浮点。ADC采进来的数据是16位做一次IIR运算保持到32位中间值最后再归一化精度完全够。这个点经常被新手忽略实际踩过坑的人都知道定点实现和浮点实现差距不小特别是系数接近临界值时浮点转定点后如果没用足够宽的中间变量会出现极限环振荡屏幕上就能看到波形在零点附近抖动。3. MCU核心功能实现与实操3.1 充气泵与泄气阀的闭环控制很多人以为血压计的充气放气不就是开关一下泵和阀嘛其实细节很多。充气阶段MCU输出PWM控制充气泵目标是快速把袖带压力提升到比收缩压高30到40mmHg左右一般取180到190mmHg。如果充气太慢测量时间长用户手会酸充气太快传感器过冲也会带来测量误差。放气阶段是最讲究的行业通用做法是放气速率控制在2到6mmHg每秒推荐3到5mmHg每秒。为了达到这个目标MCU需要每5ms读取一次当前压力值和期望的放气曲线对比然后微调泄气阀PWM。这是一个典型的PID控制回路Kp、Ki、Kd的参数需要在样机上整定。温度变化会影响阀的物理特性建议在算法里加入自适应补偿实测发现温度变化时参数偏一点放气曲线就容易出现阶梯状波动。另外充气泵的电机会产生较大电流瞬变如果供电走线和传感器模拟信号走线共享ADC读数会被明显干扰。我遇到过一例充气泵一启动压力波形里就叠加了一串高频毛刺后来排查发现是电机的地和传感器模拟地在一颗芯片下面汇合了把两者分开布地后毛刺消失。充气泵的控制PWM频率也不要选在人耳可听又容易被传感器拾取的频段一般选20kHz以上避开信号带宽。3.2 核心算法落地从ADC码值到血压值算法的完整链路我建议按阶段拆采集阶段、有效脉搏波提取阶段、包络生成阶段、血压计算阶段。每一个阶段单独测试不要等整个系统完成再一起调否则出了问题根本定位不到。采集阶段MCU启动一次测量后先打开充气泵同时连续采样压力值。为了避免充气泵对传感器读数的干扰我通常在PWM输出和ADC采集之间做一个时间交错PWM高电平期间暂停采样等低电平时再采集。这个技巧在低成本方案里很管用实测能减少不少噪声。有效脉搏波提取阶段MCU要对每次心跳产生的振荡波做判断。判断条件有三个振荡波峰值是否超过设定阈值、波的周期是否在每分钟40到120次的合理范围、波与波之间的间隔是否平稳。三者都满足才认为是有效波。这样能滤掉不少干扰比如咳嗽、手臂突然动一下、袖带漏气引起的伪波。包络生成阶段每检测到一个有效波就记录它的峰值幅度和对应的袖带压力值形成一个峰值对。随着放气过程推进所有峰值对连起来就是振荡包络。MCU实时更新最大峰值位置放气结束后再对包络做一次平滑。血压计算阶段先定位最大峰值对应的袖带压力就是MAP再分别向前后查找幅度为MAP幅度的50%和75%的位置分别对应收缩压和舒张压。这里还要做边界保护比如找不到50%点就按固定偏移估算并且对结果做合理性校验收缩压和舒张压差值小于15mmHg时视为异常提示重测。这里要特别提醒一下ADC的工作原理细节。MCU的逐次逼近型ADC在工作时采样电容会在开关闭合瞬间从外部信号源抽取一个瞬态电流如果外部信号源阻抗太高电压建立时间不够转换结果就会偏低。所以模拟输出压力传感器后面加一级电压跟随器做缓冲是非常有必要的别为了省一颗运放而导致ADC精度白白损失。3.3 低功耗与启动流程、通信接口细节血压计如果是电池供电整机功耗要算得很细。测量阶段功耗高是正常的关键在待机状态。待机时MCU进入低功耗停驻模式关闭传感器供电用外部中断唤醒。这里需要注意唤醒后不能立刻开始测量要等传感器上电稳定。压力传感器从上电到输出稳定通常需要几十到几百毫秒具体看器件手册我习惯在唤醒程序里留一个延时200ms否则第一帧压力数据往往偏得离谱。谈到MCU上电启动流程千万别忽略时钟稳定时间。MCU上电后如果直接从内部高速RC切到PLL时钟没有稳定就初始化ADC和定时器采样时间基准会漂甚至外设寄存器配置丢失。我建议MCU启动后先等待PLL锁定标志再做外设初始化。这个细节在常温下不容易暴露但在低温或电源稳定性差的场景下概率性死机就是这些细节累积出来的。通信接口方面如果BLE模块挂UART那么串口接收引脚的上拉必须注意。很多BLE模块的空闲状态是高电平若MCU引脚内部上拉并打开而模块侧没有配置上拉静态时电平还稳定但一旦通信距离变长或者线缆有点寄生电容波形沿会变差出现丢字节。我习惯在PCB上给UART_RX和UART_TX都加上外部4.7k上拉尤其是RX引脚宁可多一颗电阻也不要赌模块内部的默认状态。4. 常见问题与排查技巧实录4.1 测量结果忽高忽低先别怀疑算法每次有人拿着血压计样机找我debug说算法有问题我第一步不是调算法而是先检查物理环节。袖带尺寸有没有匹配袖带绕手臂的松紧是否一致袖带和气管接头处有没有慢性漏气这些因素对结果的影响比滤波参数大得多。举个例子袖带每次绑的松紧不一样相当于初始加压基线就不一样放气过程中示波波的传递效率也会变化最后算出来的血压值离散度自然大。实测下来同样一个人袖带绑得松一点和紧一点收缩压可以差10mmHg以上。所以软件上可以做一件事每次测量前检测袖带压力在充气初期的上升斜率斜率偏低说明可能是漏气斜率突变说明袖带可能没绑好。把这两类情况直接提示给用户比让用户看一个异常数据有用得多。4.2 ADC噪声导致的波形毛刺怎么定位ADC噪声是血压计样机调试里最常见的问题之一。要定位噪声是来自电源还是来自PCB布线我有个土办法先用外接标准电源给传感器独立供电看波形是否干净。如果干净了说明问题在电源链路优先查充气泵的电流回路看看泵的地是否和主控地单点汇合如果还是毛刺说明PCB布线或者传感器本身有问题换一颗传感器试一下。软件层面ADC过采样加均值是简单有效的办法。假如MCU的ADC采样率足够可以对每个压力点连续采16次去掉最大最小值后取平均。过采样加上均值等效于把ADC的噪声均摊掉实测可以把压力波形的峰峰值波动从几个码值降到1个码值内。不过要注意过采样频率过高会占用MCU时间片如果主循环里还有PID控制和显示刷新记得合理安排采样时序别让ADC中断把主逻辑堵死。4.3 传感器校准与整机一致性验证压力传感器出厂时每个个体都存在offset和gain误差。整机生产线上至少要标定两个点一个零点、一个满量程点。做法是给每个产品灌入稳定的标准压力记录ADC码值然后在线烧录校准系数。这个工作不能省尤其现在传感器价格压得很低误差离散度反而比早年的贵料还大。校准之后要做什么一定要做整机对比验证。我通常的做法是找一台已经过计量校准的标准血压计最好是水银柱式或经过校验的电子式在同一人同一臂上交替测量记录至少30组数据计算平均偏差和标准偏差。行业一般要求平均偏差在正负5mmHg以内标准偏差在8mmHg以内。达不到就要回头查算法参数和物理环节。不要跳过这一步直接把产品推向市场血压数据是医疗健康数据偏差会直接影响用户对产品的信任。另外再分享一个小技巧全流程自检。每次上电时MCU可以做一个漏气自检关闭泄气阀充气泵启动一小段看看压力衰减速率是否在正常范围。如果衰减过快判断为袖带或气管未接好。这个功能看起来简单但对用户体验的提升非常明显用户还没开始测设备就把故障提示出来了。4.4 算法参数调参的常见弯路很多团队把示波法算法当成黑盒直接照抄公开论文里的比例参数。但公开论文使用的数据集、袖带形态、人群和你的产品不一定匹配直接套用往往偏差很大。正确做法是先固定硬件采集足够多的临床对比数据再用数据反推适合的幅度比参数。调参时还有一个容易踩的坑包络平滑的窗口太宽。滑动平均窗口设太大包络过于平滑峰值会偏移MAP计算偏大窗口太小包络毛刺多峰值定位会乱跳。我一般先用原始包络手动标出峰值位置再反向验证平滑窗口是否合适而不是凭感觉设一个窗口就完事了。还有一点和MCU资源相关。有些项目为了节省RAM把包络存储和波形存储共用一块缓冲区结果放气还没结束之前的包络数据就被覆盖了等到计算阶段数据已经不全。这类问题在仿真环境里很难暴露因为仿真时数据量是手动控制的。建议在写代码时把缓冲区大小和最大测量时长做一次乘法估算比如200Hz采样、最多80秒测量、每个点2字节那就是32KB再留20%余量。别为了省内存把核心数据搞丢这个亏我吃过一次之后就再也不敢了。最后再分享一点我自己的体会。做血压测量方案很多人喜欢把精力花在MCU选型和算法炫技上但真正决定产品口碑的往往是那些不起眼的细节袖带的物理设计、充气阀的响应线性度、校准流程是否严格、产品在不同温湿度下的稳定性。MCU Sensor Hub把软件和硬件的边界压得很扁好处是问题解决起来灵活坏处是哪个环节出问题都会体现在最终数据上。所以调试时多留一点时间做整机一致性测试比反复调算法参数更值。后续如果你想继续深入可以在这个架构上扩展血氧、心电、体温等多生命体征融合MCU Sensor Hub天然适合这种多传感器接入的场景。

相关新闻

最新新闻

日新闻

周新闻

月新闻