2、电压测量法(OCV):开路电压与SOC关系曲线、查表法实现、温度补偿的必要性

各位同学,咱们接着聊。上一章我讲了电流积分法,也就是库仑计数。这方法好用,但有个毛病——误差会累积。你想想看,用久了,SOC 数据就像脱缰的野马,越跑越偏。

那怎么办?这时候就得请出另一位老朋友:电压测量法,也叫 OCV 法。说白了,就是通过测电池两端的开路电压,来反推当前的剩余电量。

2.1 开路电压与SOC的关系曲线

为什么电压能反映电量?这得从电池的电化学特性说起。锂电池的正负极材料,在充放电过程中,电位会随着锂离子的嵌入和脱出而变化。这个变化,最终体现在电池的端电压上。

我做过一个实验,把一颗 18650 电芯放在恒温箱里,从满电 4.2V 开始,以 0.05C 的小电流放电,每放出 5% 的电量就静置 2 小时,等电压稳定了再记录。最后画出来的曲线,就是 OCV-SOC 曲线。

这条曲线长什么样?我直接给个典型数据,你们感受一下:

SOC (%) OCV (V) 备注
100 4.20 满电状态
90 4.06 下降较快
80 3.98 平台区开始
70 3.92 平台区
60 3.87 平台区
50 3.82 平台区
40 3.77 平台区
30 3.70 开始陡降
20 3.58 下降明显
10 3.40 接近放电截止
5 3.20 赶紧充电
0 3.00 保护板会切断

看到没?这条曲线不是线性的。中间 30%-80% 这一段,电压变化很平缓,我们叫它「平台区」。而在两端,尤其是低电量区,电压掉得特别快。

核心要点:OCV-SOC 曲线的形状,决定了电压测量法的精度分布。平台区精度差,两端精度高。所以,单独用电压法,在中间段容易翻车。

2.2 查表法实现

有了曲线,怎么用?最直接的办法就是查表法。把上面那张表存到单片机的 Flash 里,ADC 测到电压后,直接查表找对应的 SOC。

具体怎么做?我给你们看一段伪代码,这是我当年在 STM32 上跑过的逻辑:

// OCV-SOC 查找表,共 11 个点
const float ocv_table[11] = {3.00, 3.20, 3.40, 3.58, 3.70, 3.77, 3.82, 3.87, 3.92, 3.98, 4.06, 4.20};
const uint8_t soc_table[11] = {0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100};

uint8_t get_soc_by_ocv(float measured_voltage)
{
    uint8_t i;
    // 边界检查
    if (measured_voltage <= ocv_table[0]) return soc_table[0];
    if (measured_voltage >= ocv_table[10]) return soc_table[10];

    // 线性插值查找
    for (i = 0; i < 10; i++)
    {
        if (measured_voltage >= ocv_table[i] && measured_voltage < ocv_table[i+1])
        {
            // 线性插值公式
            float ratio = (measured_voltage - ocv_table[i]) / (ocv_table[i+1] - ocv_table[i]);
            return soc_table[i] + (uint8_t)(ratio * (soc_table[i+1] - soc_table[i]));
        }
    }
    return 0; // 异常情况
}

这段代码的核心就两点:边界检查线性插值。边界检查防止数组越界,线性插值让结果更平滑,不会出现跳变。

我的小技巧:查表点不要均匀分布。在平台区(30%-80%),电压变化慢,点可以密一些;在两端,电压变化快,点可以疏一些。这样既能保证精度,又能节省 Flash 空间。

不过,查表法有个前提——你得保证测的是真正的开路电压。电动牙刷在运行时,电机在转,电池有电流,这时候测到的电压是工作电压,不是 OCV。所以,电压法只能在静置状态下使用。

我曾经在一个项目里踩过坑。牙刷刚停下,我就立刻测电压查表,结果 SOC 显示还有 60%,实际只有 30%。为什么?因为电池有极化效应,刚停止放电时,电压会慢慢回升,需要等几分钟才能稳定。

避坑指南:电动牙刷的静置时间建议至少 30 秒。如果条件允许,等 2 分钟再测 OCV,精度会好很多。我曾经因为赶时间,只等了 10 秒,结果 SOC 误差高达 15%。

2.3 温度补偿的必要性

好,现在你学会了查表。但问题来了——上面那张表是在 25°C 下测的。如果环境温度变了,曲线会漂移。

为什么会这样?因为温度影响电池内部的化学反应速率。低温下,电解液变粘稠,锂离子移动变慢,内阻增大,开路电压会偏低。高温下则相反,电压会偏高。

我给你们看一组实测数据,同样是 50% SOC 的电芯:

温度 (°C) OCV (V) 误差 (相对25°C)
-10 3.75 -0.07V
0 3.78 -0.04V
25 3.82 0.00V
45 3.85 +0.03V
60 3.87 +0.05V

你看,-10°C 时电压低了 0.07V。如果还用 25°C 的表去查,查出来的 SOC 可能只有 30%,实际是 50%。这误差,用户能接受吗?肯定不能。

所以,温度补偿是必须的。怎么做?我建议两种方法:

  1. 多温度查表法:在 -10°C、0°C、25°C、45°C、60°C 五个温度点各测一条 OCV-SOC 曲线,存五张表。实际使用时,根据当前温度,选择最近的两张表做线性插值。
  2. 电压修正法:只存一张 25°C 的表,然后根据温度查一个修正系数,对测量电压做偏移。比如 -10°C 时,把测到的 3.75V 加上 0.07V,变成 3.82V,再去查表。

我个人更推荐第一种。虽然占用的 Flash 多一些,但精度更高,而且不用去拟合复杂的修正公式。电动牙刷的 Flash 通常够用,存五张表也就几百个字节,完全扛得住。

总结一下:电压测量法简单直接,但有两个硬伤——一是只能在静置时用,二是受温度影响大。所以,实际产品中很少单独用 OCV 法,而是把它和电流积分法结合起来,互相校准。这个我们后面会详细讲。

嗯,今天就到这儿。下一章,我会讲卡尔曼滤波法,那才是真正把两种方法揉在一起的「大杀器」。到时候你们就知道,为什么我说 OCV 法是「定海神针」了。