宠物不会说话,发烧、食欲下降、连续十几个小时不动弹,这些异常往往要等主人下班回家才被发现。做一款能贴身的宠物健康追踪设备,第一反应不是随便找个开发板拼一拼,而是先把通信方式、功耗预算和数据模型想清楚。我们最终选定了 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 | 广播 + 连接双模式 | 低功耗优先,不支持 WiFi |
1.3 产品形态选择:项圈、背心还是贴片
形态直接影响传感器采集质量和佩戴意愿。我们对比过三种方案:
- 贴片式:贴在宠物腹部或颈部,传感接触好,但固定困难,猫容易舔掉,狗翻滚时会蹭掉。
- 背心式:传感器接触最稳,但穿戴麻烦,夏天闷热,宠物排斥度高。
- 项圈式:佩戴阻力最小,猫咪和狗都能接受,内部空间足够放电池和 PCB。缺点是 NTC 和 PPG 都只能贴近颈部侧面,无法贴在腹部测量,需要靠标定解决。
最终选择项圈式。硬件上做成一圈软性结构,电池和主板放在项圈底部,传感器朝内紧贴颈部皮肤,这样既能保证贴合度,又不会影响宠物活动。防水等级做到 IP67,毕竟狗会玩水,猫会舔毛,雨天出门也是常态。
2. Nordic BLE SoC 选型逻辑:nRF52840 和 nRF5340 为何比 ESP32-S3 更合适
2.1 候选芯片对比与选型约束
选型时列出的约束条件很明确:电池供电,峰值电流和平均功耗必须低;BLE 协议栈要成熟稳定,不能花大量时间调协议;ADC 要有足够精度来采集体温和电池电压;封装要小,方便塞进项圈;量产成本要可控。
当时考虑过几个平台:ESP32-S3、STM32WB55、Nordic nRF52840、nRF5340。对比表格如下:
| 对比项 | ESP32-S3 | STM32WB55 | Nordic nRF52840 | Nordic nRF5340 |
|---|---|---|---|---|
| 无线协议 | WiFi + BLE 5.0 | BLE 5.0 | BLE 5.0 / ANT / 802.15.4 | BLE 5.3 / ANT / 802.15.4 |
| 核心 | 双核 Xtensa LX7 @240MHz | Cortex-M4 @64MHz | Cortex-M4F @64MHz | 双核 Cortex-M33 |
| BLE RX/TX 电流 | 偏高 | 中 | RX 约4.6mA,TX@0dBm 约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 和电池电压采样需求;有足够的 Flash(1MB)和 RAM(256KB),跑 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 SDK(NCS)+ 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-AWR(Periodic Advertising with Responses)在新一代 Nordi c SoC 上支持更好,适合做双向低功耗通信;iBeacon 格式则适合做室内靠近识别,比如猫砂盆旁边放一个信标,经过时记录如厕行为。
4.3 GATT 服务设计
GATT 服务结构直接决定了 App 开发顺不顺,我们这样设计:
| 服务 | 特征 | 属性 | 说明 |
|---|---|---|---|
| Health Service | 体温 | Read / Notify | 实时体温,异常时可订阅推送 |
| Health Service | 心率 | Read / Notify | PPG 数据,选配功能 |
| Health Service | 活动量 | Read | 步数、活动时长、睡眠统计 |
| Battery Service | 电量 | Read / Notify | 标准 BLE Battery Service |
| Device Information | 序列号/版本 | Read | 产测和售后用 |
| DFU Service | 固件升级 | Write / Notify | Nordic 标准双 bank OTA |
连接参数我们也做了调整:连接间隔设在 30ms 到 50ms,slave latency 设为 3,超时 6 秒。也就是说,手机连上设备后,设备可以在大部分连接事件里保持睡眠,只有数据积压到一定程度才唤醒发送。这样既保证了数据同步的实时性,又不会让连接状态功耗过高。
4.4 OTA 升级与启动流程
OTA 是宠物穿戴设备必须做的,否则产品卖出去之后固件只能靠返厂刷写。Nordic 的双 bank DFU 方案很成熟,预留一个 bank 存新固件,校验通过后切换启动。需要注意两点:
一是 Flash 分区规划要在原理图阶段就定好,给 bootloader、app、DFU 数据区各留足空间。二是升级过程中必须维持 BLE 连接,如果中途断连,设备要能自动回滚到旧固件。我们把固件启动流程设计成:芯片上电先跑 bootrom,再跳 bootloader,bootloader 检查是否有新固件待应用,确认后再跳转到用户 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 前把调试口关闭以节省电流,结果下次固件出了 bug,J-Link 死活连不上。
遇到这类"disconnected from the target"的问题,排查路径是这样的:先确认目标板供电和复位是否正常,再用示波器看 SWD 时钟和数据线有没有波形,接着检查 J-Link 与目标板之间的接线长度,最后才考虑是不是固件里把调试口关了。如果确认是软件关闭,用 Nordic 官方的 nRF Connect Programmer 或命令行工具把芯片擦除回出厂状态就能救回来。
6.2 Android BLE 工程里的兼容性问题
Android 端 BLE 开发的坑比固件还多。先说权限:Android 6 需要定位权限才能扫描 BLE,Android 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 继续承担传感器采集和本地交互,那会是另一个更有意思的迭代方向。