本文先整理电压采样的方案设计思路,再复盘下面五类电量与充电问题:

一、电压稳定方案的设计思路

电量计算不会直接使用一次 ADC 采样结果。播放音乐、蓝牙发射和负载切换都会造成短时波动,因此在进入电量估算前,需要先得到一份相对稳定的电压。

这里先分清三个值:

数据含义
新采样电压ADC 本次换算得到的电压,每次都可能变化
平均电压经过滤波后缓慢上升或下降的中间值
稳定电压达到更新条件后才改变,提供给后续电量算法使用

稳定电压不是手机显示的百分比,也不是永远固定不变。它只是在平均电压没有达到更新条件时保持原值。

方案一:去极值后取平均值

先连续采集一组电压,去掉其中几个最大值和最小值,再对剩余数据求平均。偶发的异常高值和异常低值不会直接影响结果,适合 ADC 容易出现尖峰干扰的场景。

这种方案的优点是抗单点异常能力强,思路也比较直观。缺点是需要保存一组采样数据,还要完成极值查找或排序,会占用更多内存和计算资源。采样窗口越长,结果越稳定,但输出延迟也越大,真实电压发生变化时不容易及时跟上。

方案二:递推平均加更新阈值

递推平均不需要保存整组数据。每得到一个有效采样值,就让原来的平均电压向新采样值移动一小步。新采样值低于旧平均值时向下移动,高于旧平均值时向上移动,每次移动的大小由两者差值和递推系数决定。

这种方案的优点是内存和计算开销小,适合持续采样,也可以通过调整递推系数改变响应速度。缺点是它不会自动剔除异常值,一个突发尖峰会影响后续一段时间;系数过小,电压变化跟得慢,系数过大,又容易把短时波动带进结果。

以递推系数 1/32 为例:

  1. 当前平均电压和稳定电压都是 4000mV。
  2. 本次新采样电压为 3800mV,与平均电压相差 200mV。
  3. 本次只向下移动差值的 1/32,也就是 6.25mV,新的平均电压约为 3993.75mV。
  4. 新的平均电压再与稳定电压比较。两者向下相差约 6.25mV,达到当前项目的下降更新条件,稳定电压才更新。

如果旧平均电压低于新采样电压,处理方向相反:旧平均电压加上两者差值的 1/32,得到新的平均电压。无论差值大小,每次采样都会参与递推;更新阈值只负责决定稳定电压是否改变。

当前项目在平均电压下降约 5mV 时允许更新稳定电压,向上则需要变化约 10mV。下降阈值更小,可以及时反映放电趋势;上升阈值更大,可以减少负载解除后电压回弹带来的影响。

对于 TWS 耳机这种电压变化缓慢、需要持续采样的设备,递推平均占用资源少,也方便调整响应速度,当前 SDK 采用的就是第二种方案。如果还会出现明显的异常采样,可以先剔除异常值,再进入递推平均。

二、电量曲线

问题现象

耳机从满电持续播放音乐时,有些 10% 很快掉完,有些区间长时间不变化;左右耳在同一电量区间的续航也可能相差较大。总续航接近要求,但百分比曲线不均匀。

问题原因

这次问题的直接原因是软件仍使用旧电池的电压—电量表,与当前电芯的充放电曲线不匹配,导致各百分比区间对应的实际续航不均匀。左右耳的主从角色还会带来功耗差异,因此双耳验证时也要把主从切换考虑进去。

处理结果

根据当前电芯的实测充放电数据更新电量表,同时调整电量相关的主从切换逻辑。修改后分别在 ANC 开启和关闭场景下完成整轮放电验证,各 10% 区间的续航恢复到要求范围内。

三、温度采样

问题现象

断开 NTC 检测电阻后,系统没有识别到温度检测异常,充电也没有被禁止。

问题原因

NTC 通过分压电路接到 ADC,正常连接时会得到有效采样值,断路或短路时则会落到异常范围。原来的流程中,部分场景没有及时刷新 NTC 采样值,检测电源的初始化也不完整,断开 NTC 后仍可能读到上一次的正常值,因此充电保护没有触发。

处理结果

修正 NTC 的 ADC 刷新和检测电源初始化流程,并把断路、短路等边界值直接按异常处理。修改后断开 NTC,系统能够识别异常并禁止充电。

四、上报精度

问题现象

同一副耳机在 Google 设备页显示 95%,手机下拉状态栏却显示 100%;重新连接后,两个位置的显示结果还可能发生变化。

问题原因

Google 设备页和状态栏分别使用 GFPS 与 HFP 的电量上报。首次连接和重新连接时,HFP 协商出的电量精度可能不同,再加上两条链路使用了不同的取整规则,同一个 95% 最终可能显示成 95% 或 100%。

处理结果

将 GFPS 与 HFP 统一为 10% 精度,App 继续使用 5% 精度,同时整理首次连接和重连时的上报流程。修改后,Google 设备页与手机状态栏的电量保持一致。

五、电量管控

问题现象

产品开启电量管控,并把耳机充电上限设为 80%。耳机低电入盒并持续充电两小时后,电量仍然达到满电,没有停在设置的上限。

问题原因

电量管控虽然设置了充电上限,但达到 80% 后没有正确执行停充动作,充电流程仍然继续。

处理结果

在周期电量管理中补充上限检查:电量管控开启、耳机正在充电且当前电量达到上限时,关闭充电电流并更新管控状态。修改后持续充电两小时,耳机电量保持在 80%。

六、状态刷新

问题现象

充电盒无电时,将双耳放入盒内并插入充电线,App 正常显示充电图标;拔掉充电线后,图标却一直没有消失。

问题原因

充电状态放在盒子电量字段的最高位。拔线后,机盒没有在关机前发送清除充电标志的新状态包,耳机只能继续使用缓存中的旧状态,App 因此一直显示充电。

处理结果

机盒在拔线后、关机前补发一次最新电量状态,并清除充电标志。耳机收到新数据后更新缓存并通知 App,充电图标能够正常消失。