宠物健康监测设备实战:nRF52840 BLE SoC设计与踩坑复盘 宠物不会说话发烧、食欲下降、连续十几个小时不动弹这些异常往往要等主人下班回家才被发现。做一款能贴身的宠物健康追踪设备第一反应不是随便找个开发板拼一拼而是先把通信方式、功耗预算和数据模型想清楚。我们最终选定了 Nordic 的 BLE SoC 作为主控利用 BLE 低功耗特性做近距离数据同步和异常告警把体温、心率、活动量这些信号变成主人手机上看得懂的健康报告。这篇文章从需求拆解、芯片选型、硬件设计、固件架构、电池电量估算到开发期踩坑完整把项目复盘一遍给正在做宠物穿戴或类似低功耗 BLE 设备的朋友一些参考。1. 宠物健康追踪设备的需求拆解要采集哪些数据才不算玩具1.1 为什么宠物需要一台可穿戴健康设备宠物医疗里有个很现实的问题猫狗的耐痛能力强生病初期很难被察觉。狗可能只是活动量下降、睡觉姿势改变、体温升高零点几度猫更是喜欢藏病等到主人发现食欲不振的时候往往已经拖了几天。靠人每天观察不现实尤其上班族白天不在家宠物独自在家八到十个小时这个空窗期很长。所以这个项目的第一目标不是做好玩的智能项圈而是做一只戴在身上就能持续记录基础健康指标的设备。它不会替你诊断但能把异常变化抓住提醒主人去检查。体温、心率、活动量这三样是最核心的信号能反映大部分常见疾病的前兆比如发热、肠胃不适、关节问题、泌尿系统异常。1.2 功能定义与设计指标在立项阶段我们把功能拆成了下面这张表。注意每一项都有明确的测量方式和量化指标这是避免后期方案反复变更的关键。功能模块测量方式设计指标说明体温监测NTC 热敏电阻贴肤测量35~42°C精度 ±0.2°C皮肤表面温度不等于核心体温需要做标定映射心率监测PPG 光学传感器30~240 bpm选配功能猫狗心率范围比人宽活动量三轴加速度计计步、活动时长、睡眠分析支持行为识别静止、轻度活动、剧烈运动异常报警本地阈值判断 BLE 上报体温超限、长时间不动关键事件需要实时推送到手机续航300mAh 锂电池30 天以上每日多次连接同步BLE 广播待机通信BLE 5.0广播 连接双模式低功耗优先不支持 WiFi1.3 产品形态选择项圈、背心还是贴片形态直接影响传感器采集质量和佩戴意愿。我们对比过三种方案贴片式贴在宠物腹部或颈部传感接触好但固定困难猫容易舔掉狗翻滚时会蹭掉。背心式传感器接触最稳但穿戴麻烦夏天闷热宠物排斥度高。项圈式佩戴阻力最小猫咪和狗都能接受内部空间足够放电池和 PCB。缺点是 NTC 和 PPG 都只能贴近颈部侧面无法贴在腹部测量需要靠标定解决。最终选择项圈式。硬件上做成一圈软性结构电池和主板放在项圈底部传感器朝内紧贴颈部皮肤这样既能保证贴合度又不会影响宠物活动。防水等级做到 IP67毕竟狗会玩水猫会舔毛雨天出门也是常态。2. Nordic BLE SoC 选型逻辑nRF52840 和 nRF5340 为何比 ESP32-S3 更合适2.1 候选芯片对比与选型约束选型时列出的约束条件很明确电池供电峰值电流和平均功耗必须低BLE 协议栈要成熟稳定不能花大量时间调协议ADC 要有足够精度来采集体温和电池电压封装要小方便塞进项圈量产成本要可控。当时考虑过几个平台ESP32-S3、STM32WB55、Nordic nRF52840、nRF5340。对比表格如下对比项ESP32-S3STM32WB55Nordic nRF52840Nordic nRF5340无线协议WiFi BLE 5.0BLE 5.0BLE 5.0 / ANT / 802.15.4BLE 5.3 / ANT / 802.15.4核心双核 Xtensa LX7 240MHzCortex-M4 64MHzCortex-M4F 64MHz双核 Cortex-M33BLE RX/TX 电流偏高中RX 约4.6mATX0dBm 约4.8mA更低睡眠电流10uA 以上量级低System Off 约0.3uA接近协议栈体验可用但历史包袱多ST 封装较封闭SoftDevice / Zephyr 都很成熟Zephyr / nRF Connect SDK适合场景WiFi 云端直连工业物联网纽扣电池/小电池穿戴设备高性能穿戴设备2.2 为什么没选 ESP32-S3很多人会问ESP32-S3 自带 WiFi 和 BLE价格还便宜为什么不用原因主要有三个第一功耗账算不过来。宠物项圈的 WiFi 根本用不上而 ESP32-S3 的 BLE 射频电流和深度睡眠电流都比 Nordic 高一个量级。同样的 300mAh 电池ESP32-S3 方案可能只能撑一周Nordic 方案可以做到一个月以上。做穿戴设备续航是硬指标不是能跑通就完事。第二射频共存问题。ESP32-S3 的 WiFi 和 BLE 共用天线虽然芯片内部有共存机制但在实际项目中如果 WiFi 不是刚需就等于白白引入了一套可能造成干扰的射频系统。与其花精力处理 WiFi/BLE 共存不如直接砍掉 WiFi。第三BLE 协议栈的体验。ESP-IDF 里的 BLE 协议栈能用但遇到连接异常、广播兼容性问题时调试资料和社区积累明显不如 Nordic 丰富。Nordic 的 SoftDevice 经过大量量产设备的验证Zephyr 驱动的外设覆盖也最全。2.3 为什么最终定格在 nRF52840我们量产选的是 nRF52840理由很直接它的外设组合非常适合这个项目。nRF52840 自带 12 位 ADC满足 NTC 和电池电压采样需求有足够的 Flash1MB和 RAM256KB跑 Zephyr、做双 bank OTA 都轻松支持 BLE 5.0、ANT 和 802.15.4后续如果要做 Apple Find My 或者补充协议栈硬件不用改。还有 NFC-A tag虽然宠物场景用不太到但可以在配对时刷一下手机就完成绑定。nRF5340 双核更强但项目初期用不到这么高的算力成本和功耗都更高。我的建议是如果你的产品只需要 BLE 加传感器采集nRF52840 是性价比最优解如果后续要加复杂算法、语音处理或者更激进的低功耗策略再考虑 nRF5340 或 nRF54 系列。3. 硬件设计核心传感器布局、电源域与 ADC 抗电源纹波细节3.1 硬件系统组成整个硬件系统可以抽象成几个部分主控nRF52840 SoC负责 BLE 协议栈、传感器数据采集、数据处理和功耗管理。传感器NTC 热敏电阻测体温LIS3DH 三轴加速度计测活动预留 MAX30102 PPG 模块接口测心率。电源锂电池经过低噪声 LDO 供电模拟部分和数字部分分开去耦。指示与交互一个 RGB LED 做状态提示一个蜂鸣器做本地报警全部用 PWM/GPIO 控制。天线PCB 天线或陶瓷天线放在项圈上方远离金属件。3.2 NTC 体温测量的精度细节NTC 测体温看似简单实际最容易翻车。NTC 的阻值变化是非线性的而且需要通过电阻分压后送 ADC 采样。这里有两个关键问题一是源阻抗。nRF52840 的 ADC 是逐次逼近型输入源阻抗过高时采样电容还没有充满就会被采走导致读数偏低。NTC 分压网络的等效阻抗通常在几十千欧到几百千欧直接接 ADC 会明显影响精度。我们用了一个单位增益运放做缓冲或者把 ADC 采样时间配置到最长档位二选一。考虑到成本和功耗实际量产版本用了长采样时间方案。二是电源纹波。热词里经常有人搜rf soc 器件 gen3 adc 电源纹波这其实是个通用问题ADC 的参考电压直接来自电源电源上的纹波会原样叠加进采样结果。BLE 射频发射瞬间电流可达几毫安到几十毫安电池电压会被瞬间拉低几百毫伏如果 ADC 采样刚好撞上这个窗口读出来的温度可能跳好几度。解决方法是把 ADC 采样任务安排在射频事件完成之后通过定时器或 PPI 触发而不是随意调度。3.3 电源域设计和射频布局经验电源架构我们用了两级处理电池输出先经过一颗超低静态电流的 LDO比如 TPS7A02静态电流只有几百纳安输出噪声很低给模拟传感器和射频部分供电。数字部分SoC 内核、Flash、GPIO用另一路 LDO或者直接从主 LDO 出来后加磁珠和去耦电容隔离。这样做的原因是避免数字开关噪声通过电源耦合进模拟采样通道同时保证射频部分在高发射功率时不会因为电源跌落导致发射杂散。PCB 布局上天线净空区下方不走任何电源线和地线天线匹配网络尽量靠近芯片引脚外壳也避开金属材料否则蓝牙连接距离会从十几米掉到几米。4. BLE 协议栈与固件架构广播包、GATT 服务和 OTA 的设计取舍4.1 固件平台选择nRF5 SDK 还是 Zephyr新项目我是强烈建议直接走 nRF Connect SDKNCS Zephyr 路线。老牌的 nRF5 SDK 加 SoftDevice 资料多、上手快但已经处于维护后期新的 nRF5340、nRF54 系列都不支持了。Zephyr 的优势是驱动统一、BLE 协议栈与 RTOS 深度集成用 devicetree 管硬件后期换芯片或加外设效率高很多。但 Zephyr 的坑在于学习曲线陡配置体系复杂。如果你是第一次接触建议先跑通一个最小 BLE 外设工程再看文档逐步加传感器驱动。不要一上来就搭完整工程否则编译过了都不知道是怎么过的。4.2 广播包设计不连接也能看到摘要数据宠物项圈平时绝大多数时间处于广播状态手机在附近就能收到数据。这样用户不需要主动连接就能在 App 里看到最新的体温和电量摘要体验会好很多。广播包我们设计成Flags 字段标准 BLE 广播标志。16 位服务 UUID自定义 Health Service 的 UUID方便手机端识别。厂商自定义数据段设备类型、固件版本、电池电量百分比、体温摘要值、活动状态标志。广播间隔的选择要平衡功耗和发现速度。搜索阶段用 100ms 快速广播设备正常运行后用 1000ms 慢广播。实测下来1000ms 间隔下手机扫描基本无感电流消耗比 100ms 低很多。另外两个可以做的点P-AWRPeriodic Advertising with Responses在新一代 Nordi c SoC 上支持更好适合做双向低功耗通信iBeacon 格式则适合做室内靠近识别比如猫砂盆旁边放一个信标经过时记录如厕行为。4.3 GATT 服务设计GATT 服务结构直接决定了 App 开发顺不顺我们这样设计服务特征属性说明Health Service体温Read / Notify实时体温异常时可订阅推送Health Service心率Read / NotifyPPG 数据选配功能Health Service活动量Read步数、活动时长、睡眠统计Battery Service电量Read / Notify标准 BLE Battery ServiceDevice Information序列号/版本Read产测和售后用DFU Service固件升级Write / NotifyNordic 标准双 bank OTA连接参数我们也做了调整连接间隔设在 30ms 到 50msslave latency 设为 3超时 6 秒。也就是说手机连上设备后设备可以在大部分连接事件里保持睡眠只有数据积压到一定程度才唤醒发送。这样既保证了数据同步的实时性又不会让连接状态功耗过高。4.4 OTA 升级与启动流程OTA 是宠物穿戴设备必须做的否则产品卖出去之后固件只能靠返厂刷写。Nordic 的双 bank DFU 方案很成熟预留一个 bank 存新固件校验通过后切换启动。需要注意两点一是 Flash 分区规划要在原理图阶段就定好给 bootloader、app、DFU 数据区各留足空间。二是升级过程中必须维持 BLE 连接如果中途断连设备要能自动回滚到旧固件。我们把固件启动流程设计成芯片上电先跑 bootrom再跳 bootloaderbootloader 检查是否有新固件待应用确认后再跳转到用户 app。这套流程下即使 OTA 写到一半断电设备也能重新回到旧固件不至于变砖。5. 电池电量估算从电压查表到 EKF 容量校正的实战对比5.1 先分清两个 SoC芯片和荷电状态标题里的 SoC 是指 System on Chip也就是 nRF52840 这颗片上系统。但做电源管理的时候SOC 还有一个完全不同的含义State of Charge荷电状态也就是电池还剩多少电。这两个词在我们项目里同时出现开会时经常被搞混所以有必要说清楚。电池电量估算的难点在于负载是剧烈波动的。设备睡眠时电流只有几微安BLE 广播时跳到几毫安连接传输时瞬时电流能到几十毫安。如果用固定电压阈值去查表会出现一个经典问题在广播瞬间测得电压 3.5V查表显示电量 30%其实静置一会儿电压又恢复到 3.8V真实电量还有 60%。低电量误报会频繁发生。5.2 为什么电压查表不够用最简单的方案是离线测一条 OCV-SOC 曲线然后通过电压反查电量。但这条曲线只有在电池开路、静置足够长时间后才准确。实时工作状态下电池内部有极化效应和欧姆压降端电压不等于开路电压。尤其低温和高倍率放电时压降更大查表结果可能偏到 20% 以上。充电状态下也不能用电压查表。我们做了这样一个对比实验同一块电池在 100mA 负载下电压 3.6V 时查表显示 20%停止负载静置 10 分钟后电压回到 3.9V查表显示 70%。所以对宠物项圈这种负载波动极大的设备必须用动态模型。5.3 EKF 容量校正的落地做法我们用的是简化版 Thevenin 等效模型加扩展卡尔曼滤波EKF校正。模型结构是开路电压 OCV(SOC) 串联内阻 R0再并联一个 RC 网络描述极化效应。状态量是 SOC 和极化电压 V1输入是负载电流测量量是电池端电压。实现上做了不少简化让它在 Cortex-M4F 上跑没有压力预先标定 OCV-SOC-Temperature 的三维查找表放 Flash 里。R0、R1、C1 参数通过离线脉冲放电实验辨识。每次 ADC 采集电池电压后跑一次 EKF 更新大约每秒一次。长时间关机后重新上电用静置电压查表初始化 SOC避免记忆丢失。实际效果怎么样在 300mAh 电池、5% 到 100% 的放电区间内EKF 估算误差从电压查表的 20% 左右缩小到 5% 以内。最关键的是BLE 广播导致的电压瞬时跌落不会再触发低电量误报因为 EKF 会根据模型判断这种跌落是动态压降不是真实电量下降。如果你觉得 EKF 太重还有折中方案用电流积分库仑计数加电压限幅校正。硬件上需要一颗带电流检测的模拟前端或者用 ADC 采样低值采样电阻两端的压降。对于养宠人群少两次误报低电量的体验差异是非常明显的。6. 开发调试期的真实坑从 J-Link 断连到 Android 兼容性问题6.1 调试器连接不是每次都顺利开发中遇到的第一类坑是调试器连不上。最常见的原因是你把 Nordic 芯片的调试接口给关了。nRF52840 的配置字里可以禁用 SWD 调试口有些急于省电的低功耗教程会让你在系统 off 前把调试口关闭以节省电流结果下次固件出了 bugJ-Link 死活连不上。遇到这类disconnected from the target的问题排查路径是这样的先确认目标板供电和复位是否正常再用示波器看 SWD 时钟和数据线有没有波形接着检查 J-Link 与目标板之间的接线长度最后才考虑是不是固件里把调试口关了。如果确认是软件关闭用 Nordic 官方的 nRF Connect Programmer 或命令行工具把芯片擦除回出厂状态就能救回来。6.2 Android BLE 工程里的兼容性问题Android 端 BLE 开发的坑比固件还多。先说权限Android 6 需要定位权限才能扫描 BLEAndroid 12 开始又增加了蓝牙扫描和连接权限不动态处理会闪退。再说扫描回调部分手机要求回调不能直接在子线程里做 UI 操作否则会崩。更麻烦的是 GATT 操作不能并发连续调用 read/write 需要排成队列否则会直接失败。我们初期在 Pixel 上调试一切正常换到某国产手机后连接成功率骤降后来发现是手机对连接间隔过短、slave latency 过大的容忍度不同。解决办法是把连接参数放宽一些并做了失败重连机制。Android 端建议直接用 Nordic 的开源 Android BLE 库它把扫描、连接、队列操作都封装好了比自己手写省太多时间。有一个小坑顺便提醒很多搜索 BLE 库的人会找到 shiny.bluetoothle那是 Xamarin 方向的东西不适用于纯 .NET Framework 桌面端。搜索结果和实际场景差得很远容易被绕进去。6.3 Windows 桌面端 C# 实现 BLE 的选型量产阶段我们需要一个 Windows 产测工具用来给主板烧录、读取序列号、检查传感器是否正常。开发环境是 WinForms 加 .NET Framework 4.7.2结果发现实现 BLE 通信比预期麻烦。.NET Framework 4.7.2 本身没有内置 BLE API经典蓝牙库 32feet.NET 对 BLE 的支持也很弱。最后我们用了两条路一条是调 WinRT 的 BluetoothLE API通过包引用让 WinForms 项目能调用 UWP API另一条是使用 InTheHand.Net.Bluetooth 这类商业库它对 .NET Framework 的支持更完整。如果只是调试阶段直接用官方 nRF Connect 桌面版就够了没必要自己写工具。6.4 戴到宠物身上之后的无线环境变化最后要说的是工程板在桌面上测试一切正常不代表戴到狗身上就没问题。宠物项圈的佩戴姿态、身体水膜、金属卡扣都会吸收和反射蓝牙信号。我们的项圈在桌面上连接距离能达到 15 米戴到狗脖子上后只剩 8 米左右。原因就是天线贴近动物身体等效于天线被含水介质包围。改善方向有三个天线位置尽量放在项圈顶部远离宠物颈部地平面尽量完整不要被卡扣螺丝打断如果空间允许用陶瓷天线会比 PCB 天线更容易调出稳定的方向图。这个环节一定要在结构手板阶段就做射频实测等开模后再改天线代价会很高。项目做到这里我最大的体会是宠物健康追踪设备在硬件层面没有太多颠覆性创新真正的难度全在功耗、精度和可靠性这些细节里。BLE SoC 的选型只是第一步后续的传感器布局、ADC 采样时机、电池模型、手机兼容性每一项都需要实测数据支撑。如果让我重来一次我会从原理图阶段就把 Zephyr 和 EKF 电量模型规划进去而不是等样机出来再补。后续如果要加 GPS 定位和蜂窝远程回传可以考虑用 nRF9160 做主控BLE SoC 继续承担传感器采集和本地交互那会是另一个更有意思的迭代方向。