<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-Hans-CN">
	<id>https://wiki.photonicat.cn/index.php?action=history&amp;feed=atom&amp;title=Photonicat_2_SOC_%E8%AE%A1%E7%AE%97</id>
	<title>Photonicat 2 SOC 计算 - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.photonicat.cn/index.php?action=history&amp;feed=atom&amp;title=Photonicat_2_SOC_%E8%AE%A1%E7%AE%97"/>
	<link rel="alternate" type="text/html" href="https://wiki.photonicat.cn/index.php?title=Photonicat_2_SOC_%E8%AE%A1%E7%AE%97&amp;action=history"/>
	<updated>2026-08-31T05:10:18Z</updated>
	<subtitle>本wiki上该页面的版本历史</subtitle>
	<generator>MediaWiki 1.39.1</generator>
	<entry>
		<id>https://wiki.photonicat.cn/index.php?title=Photonicat_2_SOC_%E8%AE%A1%E7%AE%97&amp;diff=259&amp;oldid=prev</id>
		<title>Guangyingmao：​创建页面，内容为“'''光影猫2''' 不靠&quot;看电压猜电量&quot;，而是用一套完整的'''库仑计'''（Coulomb counter，又叫电量计 / fuel gauge）来算电量：像给电池装了一个水表， 进出的每一毫安秒都记账。  本页讲清楚这套系统怎么工作——从硬件怎么测，到固件怎么积分、怎么自学习、 怎么做温度补偿，再到 Linux 内核怎么把它变成 sysfs 文件。  指示灯说明见 Photonicat 2 LED 指示灯，s…”</title>
		<link rel="alternate" type="text/html" href="https://wiki.photonicat.cn/index.php?title=Photonicat_2_SOC_%E8%AE%A1%E7%AE%97&amp;diff=259&amp;oldid=prev"/>
		<updated>2026-08-30T06:34:41Z</updated>

		<summary type="html">&lt;p&gt;创建页面，内容为“&amp;#039;&amp;#039;&amp;#039;光影猫2&amp;#039;&amp;#039;&amp;#039; 不靠&amp;quot;看电压猜电量&amp;quot;，而是用一套完整的&amp;#039;&amp;#039;&amp;#039;库仑计&amp;#039;&amp;#039;&amp;#039;（Coulomb counter，又叫电量计 / fuel gauge）来算电量：像给电池装了一个水表， 进出的每一毫安秒都记账。  本页讲清楚这套系统怎么工作——从硬件怎么测，到固件怎么积分、怎么自学习、 怎么做温度补偿，再到 Linux 内核怎么把它变成 sysfs 文件。  指示灯说明见 &lt;a href=&quot;/Photonicat_2_LED_%E6%8C%87%E7%A4%BA%E7%81%AF&quot; title=&quot;Photonicat 2 LED 指示灯&quot;&gt;Photonicat 2 LED 指示灯&lt;/a&gt;，s…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;'''光影猫2''' 不靠&amp;quot;看电压猜电量&amp;quot;，而是用一套完整的'''库仑计'''（Coulomb&lt;br /&gt;
counter，又叫电量计 / fuel gauge）来算电量：像给电池装了一个水表，&lt;br /&gt;
进出的每一毫安秒都记账。&lt;br /&gt;
&lt;br /&gt;
本页讲清楚这套系统怎么工作——从硬件怎么测，到固件怎么积分、怎么自学习、&lt;br /&gt;
怎么做温度补偿，再到 Linux 内核怎么把它变成 sysfs 文件。&lt;br /&gt;
&lt;br /&gt;
指示灯说明见 [[Photonicat 2 LED 指示灯]]，sysfs 路径见 [[Photonicat 2 sysfs]]。&lt;br /&gt;
English: [[Photonicat 2 SOC Calculation]]。&lt;br /&gt;
&lt;br /&gt;
== 电压与电量的关系 ==&lt;br /&gt;
&lt;br /&gt;
锂电池的&amp;quot;电压—电量&amp;quot;曲线中段非常平。下面取固件里的'''放电 OCV 表'''&lt;br /&gt;
（去 IR 后的整包电压）：&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 整包 OCV（开路电压） !! 对应电量&lt;br /&gt;
|-&lt;br /&gt;
| 7.58 V || 70 %&lt;br /&gt;
|-&lt;br /&gt;
| 7.50 V || 60 %&lt;br /&gt;
|-&lt;br /&gt;
| 7.44 V || 50 %&lt;br /&gt;
|-&lt;br /&gt;
| 7.36 V || 40 %&lt;br /&gt;
|-&lt;br /&gt;
| 7.28 V || 30 %&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
从 70 % 掉到 30 %，电压只降了 '''0.30 V'''，平均每 1 % 电量约 '''6 mV'''；&lt;br /&gt;
而带负载时内阻压降（I×R）可达几十毫伏，误差会超过 10 %，负载越大偏差越大。&lt;br /&gt;
&lt;br /&gt;
两端则很陡：这张表里 8.34 V 是 100 %、6.34 V 是 0 %。因此固件'''两端用电压定位，&lt;br /&gt;
中间靠电流积分推进'''。&lt;br /&gt;
&lt;br /&gt;
== 总体结构 ==&lt;br /&gt;
&lt;br /&gt;
  电量 = 起点电量 − ∫(放电电流)dt + ∫(充电电流)dt&lt;br /&gt;
&lt;br /&gt;
积分需要一个起点，且误差会随时间累积，因此还要配合一套修正机制。&lt;br /&gt;
光影猫2 分为以下几层：&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 层 !! 作用&lt;br /&gt;
|-&lt;br /&gt;
| 硬件测量 || TPA626 每 100 ms 测一次电压/电流&lt;br /&gt;
|-&lt;br /&gt;
| 库仑积分 || 每 200 ms 把电流累加进 µAs 账本&lt;br /&gt;
|-&lt;br /&gt;
| OCV 融合 || 静置时用电压表反查电量，轻轻拉回积分漂移&lt;br /&gt;
|-&lt;br /&gt;
| 锚点 || 充满 / 欠压时直接把电量钉死到 100 % / 0 %&lt;br /&gt;
|-&lt;br /&gt;
| 自学习 || 满容量、内阻、空点、充电增益，每台机器各学各的&lt;br /&gt;
|-&lt;br /&gt;
| 温度补偿 || 冷天内阻变大、可用容量变少，都要修正&lt;br /&gt;
|-&lt;br /&gt;
| 显示层 || 把内部电量映射成用户看到的 1–100 %&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 一、硬件测量 ==&lt;br /&gt;
&lt;br /&gt;
测量芯片是 '''TPA626'''（I²C 电流/电压监测器，与 INA226 同类）。它串一个&lt;br /&gt;
毫欧级采样电阻在电池回路上，测电阻两端压降换算电流，同时测总线电压。&lt;br /&gt;
&lt;br /&gt;
* '''采样周期'''：约 100 ms 一次（&amp;lt;code&amp;gt;VD1_Collect&amp;lt;/code&amp;gt;）&lt;br /&gt;
* '''中值滤波'''：电压和电流各过一个中值滤波器，滤掉 I²C 偶发抖动和负载尖峰&lt;br /&gt;
* '''原始值另存一份'''：中值滤波有约 3 s 滞后，会抹平充电器插拔的电压台阶；&lt;br /&gt;
  内阻自学习需要该瞬间台阶，故固件同时保留未滤波的原始值&lt;br /&gt;
&lt;br /&gt;
=== 电流校准 ===&lt;br /&gt;
&lt;br /&gt;
采样电阻和运放都有个体误差，出厂靠精密万用表实测标定，拟合成二次多项式：&lt;br /&gt;
&lt;br /&gt;
  I_真实(mA) = C2·x² + C1·x + C0&lt;br /&gt;
&lt;br /&gt;
当前系数（2026-07-24 二轮标定，四点残差 ≤3 mA）：&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 项 !! 值 !! 说明&lt;br /&gt;
|-&lt;br /&gt;
| C2 || −4.444×10⁻⁵ || 二次项，修大电流段的非线性&lt;br /&gt;
|-&lt;br /&gt;
| C1 || 1.0411 || 一次项（增益）&lt;br /&gt;
|-&lt;br /&gt;
| C0 || +20 mA（放电）/ 0 mA（充电） || 零点偏移，分方向&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
实现细节：&lt;br /&gt;
&lt;br /&gt;
* '''先夹再算'''：抛物线在标定范围外会反向弯（顶点约 +11.7 A），故先把输入夹到&lt;br /&gt;
  ±3 A，域外按端点斜率线性延伸。&lt;br /&gt;
* '''int64 运算'''：x² 最大到 9×10⁶，乘系数后会溢出 int32。&lt;br /&gt;
* '''55 mA 死区'''：小于该值按 0 处理，避免待机时噪声累积到账本。&lt;br /&gt;
&lt;br /&gt;
== 二、库仑积分 ==&lt;br /&gt;
&lt;br /&gt;
每 '''200 ms''' 调一次 &amp;lt;code&amp;gt;coulomb_counter_update()&amp;lt;/code&amp;gt;，把电流乘以时间&lt;br /&gt;
累加进一个 '''µAs（微安秒）'''的 64 位累加器。使用 µAs 而非 mAh，可避免定点&lt;br /&gt;
除法的舍入误差长期累积。&lt;br /&gt;
&lt;br /&gt;
* 放电减、充电加&lt;br /&gt;
* 电流绝对值小于 '''30 mA''' 的部分不计入（死区，防噪声漂移）&lt;br /&gt;
* 充电方向另有一个自学习的'''增益系数'''（充电效率不是 100 %）&lt;br /&gt;
&lt;br /&gt;
== 三、OCV 融合 ==&lt;br /&gt;
&lt;br /&gt;
在'''电池接近静置'''时，用电压反查电量表对积分做小幅修正。触发条件如下，&lt;br /&gt;
全部满足才执行：&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 条件 !! 阈值 !! 说明&lt;br /&gt;
|-&lt;br /&gt;
| 电流足够小 || &amp;amp;#124;I&amp;amp;#124; ≤ 340 mA（约 0.05C） || 电流大时内阻压降的模型误差会放大&lt;br /&gt;
|-&lt;br /&gt;
| 持续足够久 || ≥ 30 s || 让极化电压和表面电荷弛豫掉&lt;br /&gt;
|-&lt;br /&gt;
| 电压变化率 || ≤ 20 mV/s || 还在动态过程中就不算静置&lt;br /&gt;
|-&lt;br /&gt;
| 电流变化率 || ≤ 2000 mA/s || 同上&lt;br /&gt;
|-&lt;br /&gt;
| 插拔宽限期 || 10 s || 充电器刚插拔，电压还没稳&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
修正采用'''加权融合'''而非直接覆盖：&lt;br /&gt;
&lt;br /&gt;
* 权重上限 '''α = 0.07'''（OCV 最多只占 7 %），且在 8 s 内从 0 线性爬升&lt;br /&gt;
* 单次修正最多 '''0.20 %'''&lt;br /&gt;
&lt;br /&gt;
因此 OCV 只对积分做渐进修正，显示电量不会跳变。&lt;br /&gt;
&lt;br /&gt;
=== 三张 OCV 表 ===&lt;br /&gt;
&lt;br /&gt;
锂电池存在'''滞回'''：同一电量下充电时端电压偏高、放电时偏低（约 30 mV/芯，&lt;br /&gt;
2S 约 ±60 mV）。固件为此设三张表：&lt;br /&gt;
&lt;br /&gt;
* '''放电表'''：进入放电模式（&amp;amp;#124;I&amp;amp;#124; &amp;gt; 900 mA）时用&lt;br /&gt;
* '''充电表'''：进入充电模式时用&lt;br /&gt;
* '''静置表（REST）'''：充放两表的平均，小电流（&amp;amp;#124;I&amp;amp;#124; ≤ 600 mA）时用&lt;br /&gt;
&lt;br /&gt;
模式切换带'''滞回'''（进 900 mA / 出 600 mA），避免在阈值附近反复切换。&lt;br /&gt;
&lt;br /&gt;
查表前先'''去 IR'''：OCV = 端电压 − I×R_pack，其中内阻取自下面的自学习值。&lt;br /&gt;
&lt;br /&gt;
== 四、锚点 ==&lt;br /&gt;
&lt;br /&gt;
中段靠积分，两端由锚点直接置位：&lt;br /&gt;
&lt;br /&gt;
* '''满电锚点'''：充电器在位、vbus ≥ 8 V 且电流已很小 → 电量 = 100 %。&lt;br /&gt;
  必须要求充电器在位：'''95 % 的静置 OCV 约 8.16 V'''，高电量静置电池易被误判为满电；&lt;br /&gt;
  劣质或欠压充电器无法充到真满，同样不给锚。&lt;br /&gt;
* '''欠压锚点'''：放到欠压关机点 → 电量 = 0 %，同时触发空点学习。&lt;br /&gt;
&lt;br /&gt;
== 五、自学习 ==&lt;br /&gt;
&lt;br /&gt;
同一批电池和板子的个体差异可超过 10 %，因此固件'''为每台机器单独学习'''&lt;br /&gt;
四个量，结果存入 data flash，掉电不丢。&lt;br /&gt;
&lt;br /&gt;
=== 5.1 满容量学习（电池老化） ===&lt;br /&gt;
&lt;br /&gt;
标称 6800 mAh 的电池用两年可能只剩 5500 mAh。满容量若写死，老化后 SOC 会偏乐观。&lt;br /&gt;
学习流程：&lt;br /&gt;
&lt;br /&gt;
# 满电锚点触发时开窗口，累计放电清零&lt;br /&gt;
# 一路放电到欠压关机点&lt;br /&gt;
# 满容量 = 累计放出的电量 + '''700 mAh'''&lt;br /&gt;
# 中途检测到充电 → 本次窗口作废&lt;br /&gt;
&lt;br /&gt;
其中 '''700 mAh''' 是关机点余量：整机不会把电池放到 0 V，在关机点&lt;br /&gt;
（约 6.3–6.45 V）包内仍剩约 700 mAh，需补回。&lt;br /&gt;
&lt;br /&gt;
学到的值换算成'''健康度'''：&lt;br /&gt;
&lt;br /&gt;
  健康度 = 学习容量 / 6800 mAh&lt;br /&gt;
&lt;br /&gt;
健康度按 EMA 缓慢融入，单次测量不会使其大幅变化。&lt;br /&gt;
&lt;br /&gt;
=== 5.2 内阻学习（电压台阶法） ===&lt;br /&gt;
&lt;br /&gt;
内阻由'''充电器插拔瞬间'''的电压台阶测得：电流突变 ΔI，电压随之突变 ΔV，&lt;br /&gt;
&lt;br /&gt;
  R = ΔV / ΔI&lt;br /&gt;
&lt;br /&gt;
条件：电压 &amp;gt; 7.8 V（近满电区，否则 OCV 本身会随电量移动而测不准）、&lt;br /&gt;
电流台阶 ≥ 300 mA、电压台阶 ≥ 15 mV。测量结果按 3/10 的权重 EMA 融入，&lt;br /&gt;
范围限制在 10–200 mΩ，默认值 50 mΩ。&lt;br /&gt;
&lt;br /&gt;
该值是'''整包回路电阻''' = 电芯本体 + 线缆/接插件（20 mΩ）+ 保护板 MOSFET（15 mΩ）。&lt;br /&gt;
去 IR 使用整包串联值，不做扣减；上位机显示&amp;quot;电芯本体内阻&amp;quot;时才减去这 35 mΩ 板级寄生。&lt;br /&gt;
&lt;br /&gt;
=== 5.3 显示空点学习 ===&lt;br /&gt;
&lt;br /&gt;
每台机器的电流计增益与实际容量存在偏差，内部 SOC 归零的时刻与硬件实际断电的&lt;br /&gt;
时刻可能不一致（表现为显示尚有 20 % 时断电）。固件不修改电流链路，而是在'''显示层'''&lt;br /&gt;
套一个每台机器自学习的线性映射：&lt;br /&gt;
&lt;br /&gt;
  显示值 = (内部SOC − 空点) × 100 / (100 − 空点)&lt;br /&gt;
&lt;br /&gt;
'''空点'''（empty）= 上一次&amp;quot;电池真的没电了&amp;quot;时的内部 SOC。学习事件包括：&lt;br /&gt;
低压关机命令、低压下主机意外死机、欠压锚点。&lt;br /&gt;
&lt;br /&gt;
并带'''向下自纠'''：放电时电压仍健康（&amp;gt; 6.8 V）而内部 SOC 已低于空点，&lt;br /&gt;
说明空点偏高，空点随之下调。换电池或学习过头可在一个放电周期内恢复。&lt;br /&gt;
&lt;br /&gt;
=== 5.4 充电增益学习 ===&lt;br /&gt;
&lt;br /&gt;
充电效率不足 100 %，充入电荷与实际存入电荷存在差异。该增益在满电锚点学习，&lt;br /&gt;
变化 ≥1 % 时落盘。&lt;br /&gt;
&lt;br /&gt;
== 六、温度补偿 ==&lt;br /&gt;
&lt;br /&gt;
板载 NTC 每 200 ms 把温度送入库仑计，用于两项修正：&lt;br /&gt;
&lt;br /&gt;
=== 6.1 内阻温度倍率 k(T) ===&lt;br /&gt;
&lt;br /&gt;
内阻随温度变化，直接影响去 IR 的准确性。倍率取 NCA 典型温度特性的分段线性近似：&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 温度 !! 内阻倍率 k(T)&lt;br /&gt;
|-&lt;br /&gt;
| −20 °C || ×3.00&lt;br /&gt;
|-&lt;br /&gt;
| −10 °C || ×2.30&lt;br /&gt;
|-&lt;br /&gt;
| 0 °C || ×1.80&lt;br /&gt;
|-&lt;br /&gt;
| 10 °C || ×1.35&lt;br /&gt;
|-&lt;br /&gt;
| 25 °C || ×1.00（基准）&lt;br /&gt;
|-&lt;br /&gt;
| 40 °C || ×0.85&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
即 −20 °C 时内阻约为常温的'''三倍'''。学习到的内阻归一到 25 °C，使用时再乘 k(T)。&lt;br /&gt;
超出 −20…40 °C 的部分按端点截断。&lt;br /&gt;
&lt;br /&gt;
=== 6.2 低温可用容量补偿 ===&lt;br /&gt;
&lt;br /&gt;
低温下电池可用容量下降（电量并未消失，只是低温下无法取出）。固件据此&lt;br /&gt;
'''把显示空点上移'''，使显示电量提前走低：&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 温度 !! 空点上移&lt;br /&gt;
|-&lt;br /&gt;
| ≥ 15 °C || 0（不补偿）&lt;br /&gt;
|-&lt;br /&gt;
| 0 °C || 约 +4 %&lt;br /&gt;
|-&lt;br /&gt;
| −10 °C || 约 +8 %&lt;br /&gt;
|-&lt;br /&gt;
| ≤ −20 °C || +12 %（封顶）&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
NTC 读数超出 −30…70 °C 视为故障，保持上一次有效温度（初值 25 °C）。&lt;br /&gt;
&lt;br /&gt;
== 七、显示曲线 ==&lt;br /&gt;
&lt;br /&gt;
内部 SOC 不直接显示，中间还有一层映射：&lt;br /&gt;
&lt;br /&gt;
* '''4 % → 显示 1 %'''&lt;br /&gt;
* '''96 % → 显示 100 %'''&lt;br /&gt;
* 中段线性（斜率 99/92），两端截断&lt;br /&gt;
&lt;br /&gt;
因此'''显示 0 % 时电池仍留有约 4 % 余量'''（另加空点以下的硬件余量），&lt;br /&gt;
可供保存工作并正常关机；充到 96 % 即显示 100 %。这是消费电子的常规做法。&lt;br /&gt;
&lt;br /&gt;
固件上报的百分比'''下限钳在 1 %'''：未关机时不显示 0 %。&lt;br /&gt;
&lt;br /&gt;
== 八、关机后的电量保持 ==&lt;br /&gt;
&lt;br /&gt;
共三条路径：&lt;br /&gt;
&lt;br /&gt;
=== 8.1 SOC 快照 ===&lt;br /&gt;
&lt;br /&gt;
运行时 SOC 每漂移 ≥5 % 就自动落盘；关机、主机断电、进待机、OTA 复位前&lt;br /&gt;
强制落盘并刷新时间戳。&lt;br /&gt;
&lt;br /&gt;
开机恢复策略：&lt;br /&gt;
&lt;br /&gt;
* '''≤12 小时'''：SOC = 快照 − 2.0 mA × Δt（按待机电流扣减），并'''禁止'''&lt;br /&gt;
  OCV 重估覆盖。&lt;br /&gt;
* '''&amp;gt;12 小时'''：快照过期，走冷启动 OCV 重估。&lt;br /&gt;
&lt;br /&gt;
=== 8.2 深睡放电估计 ===&lt;br /&gt;
&lt;br /&gt;
电池深睡时 TPA626 掉电，无法采集电流。固件进睡前记录 RTC 分钟戳，&lt;br /&gt;
唤醒后按整机待机约 '''2.0 mA''' 恒流扣减。&lt;br /&gt;
&lt;br /&gt;
=== 8.3 换电池识别 ===&lt;br /&gt;
&lt;br /&gt;
电池拔出后 RTC 掉电重置，时间倒退。固件据此判定为换电池，快照作废并重新冷启动估计。&lt;br /&gt;
判定留有 10 分钟容差，避免升级重启时误判丢弃有效快照。&lt;br /&gt;
&lt;br /&gt;
== 九、数据如何到达 Linux ==&lt;br /&gt;
&lt;br /&gt;
MCU 算完，通过 '''UART''' 把状态帧发给主机（RK3576）。主机侧有两个消费者：&lt;br /&gt;
&lt;br /&gt;
=== 9.1 内核驱动：photonicat-pm ===&lt;br /&gt;
&lt;br /&gt;
这是一个 '''serdev''' 驱动（&amp;lt;code&amp;gt;990-photonicat-pm-add-driver.patch&amp;lt;/code&amp;gt;，&lt;br /&gt;
内核 6.12），直接挂在串口上解析状态帧，然后注册成标准 Linux 设备：&lt;br /&gt;
&lt;br /&gt;
* '''power_supply''' 类 → &amp;lt;code&amp;gt;/sys/class/power_supply/battery&amp;lt;/code&amp;gt;&lt;br /&gt;
* '''RTC''' 类 → &amp;lt;code&amp;gt;/dev/rtc&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
由于注册为'''标准子系统'''，现成 Linux 工具可直接使用，无需了解私有协议：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# 电量（%），这就是上面整套算法的最终输出&lt;br /&gt;
cat /sys/class/power_supply/battery/capacity&lt;br /&gt;
&lt;br /&gt;
# 电压 µV / 电流 µA / 功率 µW&lt;br /&gt;
cat /sys/class/power_supply/battery/voltage_now&lt;br /&gt;
cat /sys/class/power_supply/battery/current_now&lt;br /&gt;
cat /sys/class/power_supply/battery/power_now&lt;br /&gt;
&lt;br /&gt;
# 能量 µWh：energy_full 是学习到的满容量，对比 energy_full_design 看老化&lt;br /&gt;
cat /sys/class/power_supply/battery/energy_now&lt;br /&gt;
cat /sys/class/power_supply/battery/energy_full&lt;br /&gt;
cat /sys/class/power_supply/battery/energy_full_design&lt;br /&gt;
&lt;br /&gt;
# 充电器在线&lt;br /&gt;
cat /sys/class/power_supply/charger/online&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''MCU 即硬件 RTC。'''板上没有独立 RTC 芯片，MCU 常供电并自行走时，&lt;br /&gt;
时间随状态帧上送。驱动将其注册为 &amp;lt;code&amp;gt;rtc_class_ops&amp;lt;/code&amp;gt;，标准工具可直接使用：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
hwclock -r          # 读 MCU 里的时间&lt;br /&gt;
hwclock -w          # 把系统时间写回 MCU&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
因此'''断网断电数日后开机时间仍准确'''。8.3 的换电池识别也依赖它：&lt;br /&gt;
RTC 掉电重置后时间会倒退。&lt;br /&gt;
&lt;br /&gt;
=== 9.2 用户态守护进程：pcat-manager ===&lt;br /&gt;
&lt;br /&gt;
内核驱动只处理状态帧中的电源部分。'''其余 UART 协议由 pcat-manager 处理'''：&lt;br /&gt;
调制解调器管理、看门狗、开关机策略、按键事件、充电阈值下发、MCU 固件升级等。&lt;br /&gt;
完整协议见 [[Photonicat 2 MCU 通讯协议]]。&lt;br /&gt;
&lt;br /&gt;
分工如下：&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 组件 !! 负责&lt;br /&gt;
|-&lt;br /&gt;
| MCU 固件 || 测量、积分、学习、补偿——所有算法&lt;br /&gt;
|-&lt;br /&gt;
| photonicat-pm（内核） || 电源/RTC 数据 → 标准 sysfs 接口&lt;br /&gt;
|-&lt;br /&gt;
| pcat-manager（用户态） || 其余协议：调制解调器、看门狗、电源策略、OTA&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
以'''充电上限'''为例：网页设置 80 % 后，pcat-manager 通过 UART 下发给 MCU，&lt;br /&gt;
MCU 存入 data flash 并直接控制充电 MOSFET。自固件 '''RA2E1260726005''' 起该设置在&lt;br /&gt;
MCU 侧持久化，复位或 OTA 后不丢失；pcat-manager 同时保留镜像，检测到 MCU 重启时重新下发。&lt;br /&gt;
&lt;br /&gt;
== 十、常见问题 ==&lt;br /&gt;
&lt;br /&gt;
;电量偶尔小幅跳动&lt;br /&gt;
:OCV 融合或锚点正在修正积分漂移。单次修正上限 0.20 %，正常情况下不会出现大跳变；&lt;br /&gt;
 若出现大跳变，通常是快照过期后走了冷启动重估。&lt;br /&gt;
&lt;br /&gt;
;冬天电量下降更快&lt;br /&gt;
:低温下可用容量下降，同时固件把显示空点上移（−10 °C 约 +8 %）。回暖后恢复。&lt;br /&gt;
&lt;br /&gt;
;充到 96 % 即显示 100 %&lt;br /&gt;
:显示曲线的设定，见第七节。同理显示 0 % 时电池仍有余量。&lt;br /&gt;
&lt;br /&gt;
;新电池是否需要校准&lt;br /&gt;
:不需要专门操作。完整放电一次（满电到自动关机）可让固件学到真实满容量和空点，&lt;br /&gt;
 日常使用也会逐步学到。&lt;br /&gt;
&lt;br /&gt;
;健康度的更新频率&lt;br /&gt;
:需要一次完整放电窗口（满电锚点 → 欠压），中途充电则本次作废，因此更新较慢，&lt;br /&gt;
 且按 EMA 缓变。&lt;/div&gt;</summary>
		<author><name>Guangyingmao</name></author>
	</entry>
</feed>