<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-Hans-CN">
	<id>https://photonicat.com/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://photonicat.com/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://photonicat.com/index.php?title=Photonicat_2_SOC_%E8%AE%A1%E7%AE%97&amp;action=history"/>
	<updated>2026-07-26T12:03:44Z</updated>
	<subtitle>本wiki上该页面的版本历史</subtitle>
	<generator>MediaWiki 1.44.2</generator>
	<entry>
		<id>https://photonicat.com/index.php?title=Photonicat_2_SOC_%E8%AE%A1%E7%AE%97&amp;diff=1030&amp;oldid=prev</id>
		<title>C2h2：​Tighten prose: state how each stage works rather than motivating it; note k(T) is a piecewise-linear NCA approximation clamped outside -20..40C; link the MCU protocol page</title>
		<link rel="alternate" type="text/html" href="https://photonicat.com/index.php?title=Photonicat_2_SOC_%E8%AE%A1%E7%AE%97&amp;diff=1030&amp;oldid=prev"/>
		<updated>2026-07-26T12:01:56Z</updated>

		<summary type="html">&lt;p&gt;Tighten prose: state how each stage works rather than motivating it; note k(T) is a piecewise-linear NCA approximation clamped outside -20..40C; link the MCU protocol page&lt;/p&gt;
&lt;a href=&quot;https://photonicat.com/index.php?title=Photonicat_2_SOC_%E8%AE%A1%E7%AE%97&amp;amp;diff=1030&amp;amp;oldid=1019&quot;&gt;显示更改&lt;/a&gt;</summary>
		<author><name>C2h2</name></author>
	</entry>
	<entry>
		<id>https://photonicat.com/index.php?title=Photonicat_2_SOC_%E8%AE%A1%E7%AE%97&amp;diff=1019&amp;oldid=prev</id>
		<title>C2h2：​Point cross-links at the renamed SOC pages directly instead of via redirects</title>
		<link rel="alternate" type="text/html" href="https://photonicat.com/index.php?title=Photonicat_2_SOC_%E8%AE%A1%E7%AE%97&amp;diff=1019&amp;oldid=prev"/>
		<updated>2026-07-26T09:25:18Z</updated>

		<summary type="html">&lt;p&gt;Point cross-links at the renamed SOC pages directly instead of via redirects&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;zh-Hans-CN&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;←上一版本&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;2026年7月26日 (日) 17:25的版本&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l7&quot;&gt;第7行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第7行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;指示灯说明见 [[Photonicat 2 LED 指示灯]]，sysfs 路径见 [[Photonicat 2 sysfs]]。&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;指示灯说明见 [[Photonicat 2 LED 指示灯]]，sysfs 路径见 [[Photonicat 2 sysfs]]。&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;English: [[&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;How &lt;/del&gt;Photonicat 2 &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Calculates &lt;/del&gt;SOC]]。&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;English: [[Photonicat 2 SOC &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Calculation&lt;/ins&gt;]]。&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== 为什么不能只看电压 ==&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== 为什么不能只看电压 ==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;!-- diff cache key pcat_wiki:diff:1.41:old-1015:rev-1019:php=table --&gt;
&lt;/table&gt;</summary>
		<author><name>C2h2</name></author>
	</entry>
	<entry>
		<id>https://photonicat.com/index.php?title=Photonicat_2_SOC_%E8%AE%A1%E7%AE%97&amp;diff=1015&amp;oldid=prev</id>
		<title>C2h2：​C2h2移动页面光影猫2 是如何计算电量的至Photonicat 2 SOC 计算：​Align with the Photonicat 2 topic prefix used by sibling pages</title>
		<link rel="alternate" type="text/html" href="https://photonicat.com/index.php?title=Photonicat_2_SOC_%E8%AE%A1%E7%AE%97&amp;diff=1015&amp;oldid=prev"/>
		<updated>2026-07-26T09:24:50Z</updated>

		<summary type="html">&lt;p&gt;C2h2移动页面&lt;a href=&quot;/wiki/%E5%85%89%E5%BD%B1%E7%8C%AB2_%E6%98%AF%E5%A6%82%E4%BD%95%E8%AE%A1%E7%AE%97%E7%94%B5%E9%87%8F%E7%9A%84&quot; class=&quot;mw-redirect&quot; title=&quot;光影猫2 是如何计算电量的&quot;&gt;光影猫2 是如何计算电量的&lt;/a&gt;至&lt;a href=&quot;/wiki/Photonicat_2_SOC_%E8%AE%A1%E7%AE%97&quot; title=&quot;Photonicat 2 SOC 计算&quot;&gt;Photonicat 2 SOC 计算&lt;/a&gt;：​Align with the Photonicat 2 topic prefix used by sibling pages&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;zh-Hans-CN&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;←上一版本&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;2026年7月26日 (日) 17:24的版本&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;4&quot; class=&quot;diff-notice&quot; lang=&quot;zh-Hans-CN&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;（没有差异）&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;!-- diff cache key pcat_wiki:diff:1.41:old-1008:rev-1015 --&gt;
&lt;/table&gt;</summary>
		<author><name>C2h2</name></author>
	</entry>
	<entry>
		<id>https://photonicat.com/index.php?title=Photonicat_2_SOC_%E8%AE%A1%E7%AE%97&amp;diff=1008&amp;oldid=prev</id>
		<title>C2h2：​Fix: use &amp;#124; entity for absolute-value bars; backslash escapes are not MediaWiki syntax and rendered literally</title>
		<link rel="alternate" type="text/html" href="https://photonicat.com/index.php?title=Photonicat_2_SOC_%E8%AE%A1%E7%AE%97&amp;diff=1008&amp;oldid=prev"/>
		<updated>2026-07-26T09:21:36Z</updated>

		<summary type="html">&lt;p&gt;Fix: use | entity for absolute-value bars; backslash escapes are not MediaWiki syntax and rendered literally&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;zh-Hans-CN&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;←上一版本&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;2026年7月26日 (日) 17:21的版本&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l114&quot;&gt;第114行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第114行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;! 条件 !! 阈值 !! 为什么&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;! 条件 !! 阈值 !! 为什么&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|-&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|-&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;| 电流足够小 || &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;\|&lt;/del&gt;I&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;\| &lt;/del&gt;≤ 340 mA（约 0.05C） || 电流大时内阻压降的模型误差会放大&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;| 电流足够小 || &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;amp;#124;&lt;/ins&gt;I&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;amp;#124; &lt;/ins&gt;≤ 340 mA（约 0.05C） || 电流大时内阻压降的模型误差会放大&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|-&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|-&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;| 持续足够久 || ≥ 30 s || 让极化电压和表面电荷弛豫掉&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;| 持续足够久 || ≥ 30 s || 让极化电压和表面电荷弛豫掉&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l138&quot;&gt;第138行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第138行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;30 mV/芯，2S 约 ±60 mV）。所以固件带三张表：&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;30 mV/芯，2S 约 ±60 mV）。所以固件带三张表：&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* &#039;&#039;&#039;放电表&#039;&#039;&#039;：进入放电模式（&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;\|&lt;/del&gt;I&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;\| &lt;/del&gt;&amp;gt; 900 mA）时用&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* &#039;&#039;&#039;放电表&#039;&#039;&#039;：进入放电模式（&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;amp;#124;&lt;/ins&gt;I&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;amp;#124; &lt;/ins&gt;&amp;gt; 900 mA）时用&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* &amp;#039;&amp;#039;&amp;#039;充电表&amp;#039;&amp;#039;&amp;#039;：进入充电模式时用&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* &amp;#039;&amp;#039;&amp;#039;充电表&amp;#039;&amp;#039;&amp;#039;：进入充电模式时用&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* &#039;&#039;&#039;静置表（REST）&#039;&#039;&#039;：充放两表的平均，小电流（&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;\|&lt;/del&gt;I&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;\| &lt;/del&gt;≤ 600 mA）时用&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* &#039;&#039;&#039;静置表（REST）&#039;&#039;&#039;：充放两表的平均，小电流（&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;amp;#124;&lt;/ins&gt;I&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;amp;#124; &lt;/ins&gt;≤ 600 mA）时用&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;模式切换带&amp;#039;&amp;#039;&amp;#039;滞回&amp;#039;&amp;#039;&amp;#039;（进 900 mA / 出 600 mA），避免在阈值附近反复横跳。&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;模式切换带&amp;#039;&amp;#039;&amp;#039;滞回&amp;#039;&amp;#039;&amp;#039;（进 900 mA / 出 600 mA），避免在阈值附近反复横跳。&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;!-- diff cache key pcat_wiki:diff:1.41:old-1006:rev-1008:php=table --&gt;
&lt;/table&gt;</summary>
		<author><name>C2h2</name></author>
	</entry>
	<entry>
		<id>https://photonicat.com/index.php?title=Photonicat_2_SOC_%E8%AE%A1%E7%AE%97&amp;diff=1006&amp;oldid=prev</id>
		<title>C2h2：​Create: how the coulomb counter computes SOC (hardware, integration, OCV fusion, self-learning, temperature, Linux sysfs/RTC chain)</title>
		<link rel="alternate" type="text/html" href="https://photonicat.com/index.php?title=Photonicat_2_SOC_%E8%AE%A1%E7%AE%97&amp;diff=1006&amp;oldid=prev"/>
		<updated>2026-07-26T09:21:06Z</updated>

		<summary type="html">&lt;p&gt;Create: how the coulomb counter computes SOC (hardware, integration, OCV fusion, self-learning, temperature, Linux sysfs/RTC chain)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&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&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: [[How Photonicat 2 Calculates SOC]]。&lt;br /&gt;
&lt;br /&gt;
== 为什么不能只看电压 ==&lt;br /&gt;
&lt;br /&gt;
这是所有电量计要解决的第一个问题。锂电池的&amp;quot;电压—电量&amp;quot;曲线中段非常平。&lt;br /&gt;
下面取固件里的&amp;#039;&amp;#039;&amp;#039;放电 OCV 表&amp;#039;&amp;#039;&amp;#039;（去 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 %，电压只降了 &amp;#039;&amp;#039;&amp;#039;0.30 V&amp;#039;&amp;#039;&amp;#039;——平均每 1 % 电量只对应约&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;6 mV&amp;#039;&amp;#039;&amp;#039;。而电池一带负载，内阻上的压降（I×R）轻松就有几十毫伏。也就是说：&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;只看电压，误差可以轻松超过 10 %&amp;#039;&amp;#039;&amp;#039;，而且负载越大错得越离谱。&lt;br /&gt;
&lt;br /&gt;
反过来，两端却很陡：这张表里 8.34 V 是 100 %、6.34 V 是 0 %。所以正确做法是&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;两端用电压定位，中间靠积分推进&amp;#039;&amp;#039;&amp;#039;——这正是下面这套系统在做的事。&lt;br /&gt;
&lt;br /&gt;
== 一句话原理 ==&lt;br /&gt;
&lt;br /&gt;
  电量 = 起点电量 − ∫(放电电流)dt + ∫(充电电流)dt&lt;br /&gt;
&lt;br /&gt;
积分本身很准（电流测得准的话），但有两个毛病：&amp;#039;&amp;#039;&amp;#039;起点从哪来&amp;#039;&amp;#039;&amp;#039;，以及&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;误差会累积&amp;#039;&amp;#039;&amp;#039;。所以真正的电量计 = 积分 + 一套修正机制。光影猫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;
测量芯片是 &amp;#039;&amp;#039;&amp;#039;TPA626&amp;#039;&amp;#039;&amp;#039;（I²C 电流/电压监测器，与 INA226 同类）。它串一个&lt;br /&gt;
毫欧级采样电阻在电池回路上，测电阻两端压降换算电流，同时测总线电压。&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;采样周期&amp;#039;&amp;#039;&amp;#039;：约 100 ms 一次（&amp;lt;code&amp;gt;VD1_Collect&amp;lt;/code&amp;gt;）&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;中值滤波&amp;#039;&amp;#039;&amp;#039;：电压和电流各过一个中值滤波器，滤掉 I²C 偶发抖动和负载尖峰&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;原始值另存一份&amp;#039;&amp;#039;&amp;#039;：中值滤波有约 3 s 滞后，会把&amp;quot;充电器插拔的电压台阶&amp;quot;&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;
* &amp;#039;&amp;#039;&amp;#039;先夹再算&amp;#039;&amp;#039;&amp;#039;：抛物线在标定范围外会&amp;quot;反向弯&amp;quot;（顶点约 +11.7 A），所以先把&lt;br /&gt;
  输入夹到 ±3 A，域外按端点斜率线性延伸，不让二次项跑飞。&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;int64 运算&amp;#039;&amp;#039;&amp;#039;：x² 最大到 9×10⁶，乘上系数会溢出 int32。&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;55 mA 死区&amp;#039;&amp;#039;&amp;#039;：小于这个值直接当 0，避免待机时账本被噪声慢慢推歪。&lt;br /&gt;
&lt;br /&gt;
== 二、库仑积分：账本 ==&lt;br /&gt;
&lt;br /&gt;
每 &amp;#039;&amp;#039;&amp;#039;200 ms&amp;#039;&amp;#039;&amp;#039; 调一次 &amp;lt;code&amp;gt;coulomb_counter_update()&amp;lt;/code&amp;gt;，把电流乘以时间&lt;br /&gt;
累加进一个 &amp;#039;&amp;#039;&amp;#039;µAs（微安秒）&amp;#039;&amp;#039;&amp;#039;的 64 位账本。用 µAs 而不是 mAh 是为了避免定点&lt;br /&gt;
除法的舍入误差在长时间运行后累积。&lt;br /&gt;
&lt;br /&gt;
* 放电减、充电加&lt;br /&gt;
* 电流绝对值小于 &amp;#039;&amp;#039;&amp;#039;30 mA&amp;#039;&amp;#039;&amp;#039; 的部分不计入（死区，防噪声漂移）&lt;br /&gt;
* 充电方向另有一个自学习的&amp;#039;&amp;#039;&amp;#039;增益系数&amp;#039;&amp;#039;&amp;#039;（充电效率不是 100 %）&lt;br /&gt;
&lt;br /&gt;
== 三、OCV 融合：把漂移拉回来 ==&lt;br /&gt;
&lt;br /&gt;
积分误差会累积，所以在&amp;#039;&amp;#039;&amp;#039;电池接近静置&amp;#039;&amp;#039;&amp;#039;时，用电压反查电量表来轻轻纠正。&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;
| 电流足够小 || \|I\| ≤ 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;
满足后也不是直接覆盖，而是&amp;#039;&amp;#039;&amp;#039;加权融合&amp;#039;&amp;#039;&amp;#039;：&lt;br /&gt;
&lt;br /&gt;
* 权重上限 &amp;#039;&amp;#039;&amp;#039;α = 0.07&amp;#039;&amp;#039;&amp;#039;（OCV 最多只占 7 %），且在 8 s 内从 0 线性爬升&lt;br /&gt;
* 单次修正最多 &amp;#039;&amp;#039;&amp;#039;0.20 %&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
换句话说，OCV 是&amp;quot;温柔地把积分往回拽&amp;quot;，而不是&amp;quot;一把拽过去&amp;quot;——这样用户看到的&lt;br /&gt;
电量不会跳变。&lt;br /&gt;
&lt;br /&gt;
=== 三张 OCV 表 ===&lt;br /&gt;
&lt;br /&gt;
锂电池有&amp;#039;&amp;#039;&amp;#039;滞回&amp;#039;&amp;#039;&amp;#039;现象：同样的电量，充电时端电压偏高、放电时偏低（约&lt;br /&gt;
30 mV/芯，2S 约 ±60 mV）。所以固件带三张表：&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;放电表&amp;#039;&amp;#039;&amp;#039;：进入放电模式（\|I\| &amp;gt; 900 mA）时用&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;充电表&amp;#039;&amp;#039;&amp;#039;：进入充电模式时用&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;静置表（REST）&amp;#039;&amp;#039;&amp;#039;：充放两表的平均，小电流（\|I\| ≤ 600 mA）时用&lt;br /&gt;
&lt;br /&gt;
模式切换带&amp;#039;&amp;#039;&amp;#039;滞回&amp;#039;&amp;#039;&amp;#039;（进 900 mA / 出 600 mA），避免在阈值附近反复横跳。&lt;br /&gt;
&lt;br /&gt;
查表前还要先&amp;#039;&amp;#039;&amp;#039;去 IR&amp;#039;&amp;#039;&amp;#039;：OCV = 端电压 − I×R_pack，用的就是下面自学习到的内阻。&lt;br /&gt;
&lt;br /&gt;
== 四、锚点：两端归位 ==&lt;br /&gt;
&lt;br /&gt;
中段靠积分，两端靠锚点直接钉死：&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;满电锚点&amp;#039;&amp;#039;&amp;#039;：充电器在位、且 vbus ≥ 8 V、且电流已经很小 → 电量 = 100 %。&lt;br /&gt;
  要求充电器在位是有原因的：&amp;#039;&amp;#039;&amp;#039;95 % 的静置 OCV 约 8.16 V&amp;#039;&amp;#039;&amp;#039;，一块高电量的&lt;br /&gt;
  电池静置着很容易被误判成满电。劣质或欠压的充电器推不到真满，也不给锚。&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;欠压锚点&amp;#039;&amp;#039;&amp;#039;：放到欠压关机点 → 电量 = 0 %，同时触发空点学习。&lt;br /&gt;
&lt;br /&gt;
== 五、自学习：每台机器都不一样 ==&lt;br /&gt;
&lt;br /&gt;
这是这套系统最有意思的部分。同一批电池、同一批板子，个体差异也能有&lt;br /&gt;
10 % 以上。所以固件会&amp;#039;&amp;#039;&amp;#039;为每台机器单独学习&amp;#039;&amp;#039;&amp;#039;四个量，学到的值存进 data flash，&lt;br /&gt;
掉电不丢。&lt;br /&gt;
&lt;br /&gt;
=== 5.1 满容量学习（电池老化） ===&lt;br /&gt;
&lt;br /&gt;
标称 6800 mAh 的电池，用两年可能只剩 5500 mAh。如果满容量写死，老化后&lt;br /&gt;
SOC 就会偏乐观——显示还有电，实际已经关机了。&lt;br /&gt;
&lt;br /&gt;
学习方法：&lt;br /&gt;
&lt;br /&gt;
# 满电锚点触发时开窗口，累计放电清零&lt;br /&gt;
# 一路放电到欠压关机点&lt;br /&gt;
# 满容量 = 累计放出的电量 + &amp;#039;&amp;#039;&amp;#039;700 mAh&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
# 中途检测到充电 → 本次窗口作废&lt;br /&gt;
&lt;br /&gt;
那个 &amp;#039;&amp;#039;&amp;#039;700 mAh&amp;#039;&amp;#039;&amp;#039; 是关键：整机不会把电池放到真正的 0 V，在关机点&lt;br /&gt;
（约 6.3–6.45 V）时电池包里还剩约 700 mAh 没放出来，必须补回去。&lt;br /&gt;
&lt;br /&gt;
学到的值还会换算成&amp;#039;&amp;#039;&amp;#039;健康度&amp;#039;&amp;#039;&amp;#039;：&lt;br /&gt;
&lt;br /&gt;
  健康度 = 学习容量 / 6800 mAh&lt;br /&gt;
&lt;br /&gt;
健康度采用 EMA 缓慢融入（Apple 式缓变），不会因为一次测量就跳水。&lt;br /&gt;
&lt;br /&gt;
=== 5.2 内阻学习（电压台阶法） ===&lt;br /&gt;
&lt;br /&gt;
去 IR 计算需要知道内阻。固件用一个很巧的办法：&amp;#039;&amp;#039;&amp;#039;充电器插拔的瞬间&amp;#039;&amp;#039;&amp;#039;，&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;
注意这测到的是&amp;#039;&amp;#039;&amp;#039;整包回路电阻&amp;#039;&amp;#039;&amp;#039; = 电芯本体 + 线缆/接插件（20 mΩ）+&lt;br /&gt;
保护板 MOSFET（15 mΩ）。去 IR 需要的正是这个整包串联值，不做扣减；&lt;br /&gt;
上位机若要显示&amp;quot;电芯本体内阻&amp;quot;，才减掉那 35 mΩ 的板级寄生。&lt;br /&gt;
&lt;br /&gt;
=== 5.3 显示空点学习 ===&lt;br /&gt;
&lt;br /&gt;
实测踩过的坑：&amp;#039;&amp;#039;&amp;#039;显示还有 20 % 时整机突然断电&amp;#039;&amp;#039;&amp;#039;。原因是每台机器的电流计&lt;br /&gt;
增益和实际容量都有偏差，内部 SOC 到 0 的那一刻和硬件真正撑不住的那一刻对不齐。&lt;br /&gt;
&lt;br /&gt;
解法不是去改电流链路（那会引入新的误差），而是在&amp;#039;&amp;#039;&amp;#039;显示层&amp;#039;&amp;#039;&amp;#039;加一个&lt;br /&gt;
每台机器自学习的线性映射：&lt;br /&gt;
&lt;br /&gt;
  显示值 = (内部SOC − 空点) × 100 / (100 − 空点)&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;空点&amp;#039;&amp;#039;&amp;#039;（empty）= 上一次&amp;quot;电池真的没电了&amp;quot;时的内部 SOC。学习事件包括：&lt;br /&gt;
低压关机命令、低压下主机意外死机、欠压锚点。&lt;br /&gt;
&lt;br /&gt;
还有&amp;#039;&amp;#039;&amp;#039;向下自纠&amp;#039;&amp;#039;&amp;#039;：如果放电时电压还很健康（&amp;gt; 6.8 V）但内部 SOC 已经低于&lt;br /&gt;
空点，说明空点学高了，就让空点跟着降。这样换了新电池或学过头，都能在一个&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 的准确性：&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 时内阻是常温的&amp;#039;&amp;#039;&amp;#039;三倍&amp;#039;&amp;#039;&amp;#039;。学习到的内阻归一在 25 °C 域，&lt;br /&gt;
用的时候再乘 k(T)。&lt;br /&gt;
&lt;br /&gt;
=== 6.2 低温可用容量补偿 ===&lt;br /&gt;
&lt;br /&gt;
冷天电池的可用容量会缩水——不是电&amp;quot;没了&amp;quot;，而是低温下拿不出来。固件的处理是&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;把显示空点上移&amp;#039;&amp;#039;&amp;#039;，让显示电量提前走低，用户就不会在 −10 °C 的户外被&lt;br /&gt;
&amp;quot;还有 15 %&amp;quot;骗了：&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;
== 七、显示曲线：为什么是&amp;quot;特斯拉式&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
内部算出来的 SOC 不会直接给用户看，中间还有一层映射：&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;4 % → 显示 1 %&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;96 % → 显示 100 %&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* 中段线性（斜率 99/92），两端截断&lt;br /&gt;
&lt;br /&gt;
这样做的意思是：&amp;#039;&amp;#039;&amp;#039;显示到 0 % 时，电池里其实还留着约 4 % 的余量&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
（再加上空点以下的硬件余量），用户有时间保存工作、正常关机。同理，充到&lt;br /&gt;
96 % 就显示 100 %，避免用户盯着最后几个百分点焦虑——这些都是消费电子的&lt;br /&gt;
常规做法。&lt;br /&gt;
&lt;br /&gt;
另外固件上报的百分比&amp;#039;&amp;#039;&amp;#039;下限钳在 1 %&amp;#039;&amp;#039;&amp;#039;：只要还没关机，就不显示 0 %。&lt;br /&gt;
&lt;br /&gt;
== 八、关机之后：电量怎么不丢 ==&lt;br /&gt;
&lt;br /&gt;
这是很多电量计做不好的地方。光影猫2 有三条路径：&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;
* &amp;#039;&amp;#039;&amp;#039;≤12 小时&amp;#039;&amp;#039;&amp;#039;：SOC = 快照 − 2.0 mA × Δt（按待机电流扣减），并&amp;#039;&amp;#039;&amp;#039;禁止&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
  OCV 重估覆盖。这条修的是&amp;quot;短时重启后 10 % 变 1 %&amp;quot;的老问题。&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;&amp;gt;12 小时&amp;#039;&amp;#039;&amp;#039;：快照过期，走冷启动 OCV 重估。&lt;br /&gt;
&lt;br /&gt;
=== 8.2 深睡放电估计 ===&lt;br /&gt;
&lt;br /&gt;
电池深睡时 TPA626 会掉电，采不到电流。固件在进睡前记下 RTC 分钟戳，&lt;br /&gt;
醒来后按整机待机约 &amp;#039;&amp;#039;&amp;#039;2.0 mA&amp;#039;&amp;#039;&amp;#039; 恒流扣减。&lt;br /&gt;
&lt;br /&gt;
=== 8.3 换电池识别 ===&lt;br /&gt;
&lt;br /&gt;
电池拔掉 → RTC 掉电重置 → 时间倒退。固件据此判定&amp;quot;换过电池&amp;quot;，让快照作废，&lt;br /&gt;
重新冷启动估计。（这里留了 10 分钟容差，否则升级重启后一条有效快照会被误判&lt;br /&gt;
丢掉，SOC 就会出现台阶跳变。）&lt;br /&gt;
&lt;br /&gt;
== 九、数据怎么到 Linux ==&lt;br /&gt;
&lt;br /&gt;
MCU 算完，通过 &amp;#039;&amp;#039;&amp;#039;UART&amp;#039;&amp;#039;&amp;#039; 把状态帧发给主机（RK3576）。主机侧有两个消费者：&lt;br /&gt;
&lt;br /&gt;
=== 9.1 内核驱动：photonicat-pm ===&lt;br /&gt;
&lt;br /&gt;
这是一个 &amp;#039;&amp;#039;&amp;#039;serdev&amp;#039;&amp;#039;&amp;#039; 驱动（&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;
* &amp;#039;&amp;#039;&amp;#039;power_supply&amp;#039;&amp;#039;&amp;#039; 类 → &amp;lt;code&amp;gt;/sys/class/power_supply/battery&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;RTC&amp;#039;&amp;#039;&amp;#039; 类 → &amp;lt;code&amp;gt;/dev/rtc&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
因为注册的是&amp;#039;&amp;#039;&amp;#039;标准子系统&amp;#039;&amp;#039;&amp;#039;，所以任何现成的 Linux 工具都能直接用，&lt;br /&gt;
不需要认识光影猫的私有协议：&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;
&amp;#039;&amp;#039;&amp;#039;MCU 就是硬件 RTC。&amp;#039;&amp;#039;&amp;#039;板子上没有单独的 RTC 芯片——MCU 一直有电，它自己&lt;br /&gt;
就在走时，时间随状态帧一起送上来。驱动把它注册成 &amp;lt;code&amp;gt;rtc_class_ops&amp;lt;/code&amp;gt;，&lt;br /&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;
这也是为什么&amp;#039;&amp;#039;&amp;#039;断网断电放几天，开机时间还是准的&amp;#039;&amp;#039;&amp;#039;。前面 8.3 讲的&lt;br /&gt;
&amp;quot;换电池识别&amp;quot;也是靠它——RTC 掉电重置，时间就会倒退。&lt;br /&gt;
&lt;br /&gt;
=== 9.2 用户态守护进程：pcat-manager ===&lt;br /&gt;
&lt;br /&gt;
内核驱动只认状态帧里的电源部分。&amp;#039;&amp;#039;&amp;#039;其余的 UART 协议由 pcat-manager 处理&amp;#039;&amp;#039;&amp;#039;：&lt;br /&gt;
调制解调器管理、看门狗、开关机策略、按键事件、充电阈值下发、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;
一个具体例子是&amp;#039;&amp;#039;&amp;#039;充电上限&amp;#039;&amp;#039;&amp;#039;：你在网页里设 80 %，pcat-manager 通过 UART 下发给&lt;br /&gt;
MCU，MCU 把它存进 data flash 并直接控制充电 MOSFET。固件&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;RA2E1260726005&amp;#039;&amp;#039;&amp;#039; 起这个设置在 MCU 侧持久化，MCU 复位或 OTA 之后不会丢；&lt;br /&gt;
同时 pcat-manager 也保留一份镜像并在检测到 MCU 重启时重新下发，双保险。&lt;br /&gt;
&lt;br /&gt;
== 十、常见问题 ==&lt;br /&gt;
&lt;br /&gt;
;为什么电量偶尔会&amp;quot;跳一下&amp;quot;？&lt;br /&gt;
:多半是 OCV 融合或锚点在纠正积分漂移。单次修正被限制在 0.20 %，所以正常情况&lt;br /&gt;
 你不会看到大跳变；如果出现大跳变，通常是快照过期后走了冷启动重估。&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;
;新电池要不要&amp;quot;校准&amp;quot;？&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>C2h2</name></author>
	</entry>
</feed>