4、电池状态估算(一):SOC估算方法概述、安时积分法原理与实现、开路电压法原理与实现

各位工程师朋友,大家好。今天我们聊聊电池状态估算,尤其是SOC——也就是电池还剩多少电。这玩意儿,说白了就是BMS的“灵魂”。你想想看,如果连电池还有多少电都搞不清楚,那后面的均衡、热管理、寿命预测,全都是空中楼阁。

我个人习惯把SOC估算比作“猜油箱里的油”。但电池比油箱复杂多了,它是个化学系统,非线性、时变、还受温度影响。嗯,这里要注意,SOC不能直接测量,只能靠算法去“猜”。今天我们先讲两种最基础、最常用的方法:安时积分法和开路电压法。

核心观点: 安时积分法负责“短期精度”,开路电压法负责“长期校准”。两者结合,才是工程上的王道。

4.1 SOC估算方法概述

先给大家画个知识框架图,看看SOC估算这个大家族里都有哪些成员。

SOC估算方法体系 SOC估算方法 实时估算方法 模型/数据驱动方法 校准/辅助方法 安时积分法(Ah Counting) 开路电压法(OCV) 卡尔曼滤波(EKF/UKF) 神经网络/机器学习 电压查表法 满充/满放校准 工程实践:安时积分 + OCV校准 + 卡尔曼滤波 = 黄金组合 (本章重点:安时积分法 + 开路电压法)

从图上你能看到,SOC估算方法大致分三类。今天咱们就聚焦在最左边那两个:安时积分法和开路电压法。为什么先讲它们?因为这是所有BMS工程师的“基本功”,也是后续复杂算法的基础。

4.2 安时积分法原理与实现

安时积分法,名字听着挺唬人,其实原理特别简单。就是一句话:电池充进去多少电,放出来多少电,用初始电量一加一减,就得到当前电量了。

公式长这样:

SOC(t) = SOC(0) - (1 / Q_n) * ∫ η * I(t) dt

其中:

  • SOC(t):当前时刻的SOC
  • SOC(0):初始SOC(这个值很关键,后面会讲)
  • Q_n:电池额定容量(单位:Ah)
  • η:库仑效率(充电一般取0.98~1.0,放电取1.0)
  • I(t):电流(充电为正,放电为负)

说白了,这就是个“积分器”。电流采样进来,乘以时间,累加起来,再除以总容量,就得到SOC变化量。

我的经验: 我在项目中遇到过一个问题——电流采样精度不够。当时用的霍尔传感器,零漂有±10mA。别小看这10mA,积分一小时后,SOC误差能漂到1%以上。所以我建议,做安时积分法,电流采样精度至少要做到±5mA以内,最好用分流器+高精度ADC。

4.2.1 代码实现(C语言伪代码)

下面给出一段简单的安时积分实现。实际项目中会复杂得多,但核心逻辑就这些:

// 安时积分法实现(简化版)
typedef struct {
    float soc;          // 当前SOC (0~100%)
    float capacity;     // 电池额定容量 (Ah)
    float accumulated_ah; // 累积安时数 (Ah)
    float coulomb_eff;  // 库仑效率
} AhIntegrator;

void AhIntegrator_Init(AhIntegrator *ah, float init_soc, float capacity) {
    ah->soc = init_soc;
    ah->capacity = capacity;
    ah->accumulated_ah = 0.0f;
    ah->coulomb_eff = 0.99f;  // 典型值
}

void AhIntegrator_Update(AhIntegrator *ah, float current, float dt) {
    // current: 正为充电,负为放电 (单位: A)
    // dt: 采样间隔 (单位: h)
    
    float dq = current * dt;  // 电量变化 (Ah)
    
    // 充电时考虑库仑效率
    if (current > 0) {
        dq *= ah->coulomb_eff;
    }
    
    ah->accumulated_ah += dq;
    ah->soc = (ah->accumulated_ah / ah->capacity) * 100.0f;
    
    // 限幅处理
    if (ah->soc > 100.0f) ah->soc = 100.0f;
    if (ah->soc < 0.0f) ah->soc = 0.0f;
}

避坑指南: 我曾经犯过一个低级错误——忘记处理电流方向。放电时电流是负值,积分后SOC应该下降。结果我代码里忘了取绝对值,导致放电时SOC反而上升。嗯,这种bug查起来真要命。所以写代码时,一定要把电流方向、符号逻辑理清楚。

4.2.2 安时积分法的优缺点

优点 缺点
实现简单,计算量小 误差会累积(开环积分)
实时性好,适合动态工况 需要准确的初始SOC
对硬件要求低 受电流采样精度影响大
短时间精度高 无法修正自身误差

你看,安时积分法最大的问题就是“开环”。误差只会越来越大,不会自己收敛。所以我们需要另一个方法来“校准”它——这就是开路电压法。

4.3 开路电压法原理与实现

开路电压法,英文叫OCV(Open Circuit Voltage)。原理也很直观:电池在静置足够长时间后,其端电压与SOC之间存在一一对应的关系。 你测出电压,查表就能知道SOC。

为什么会这样?因为电池的化学反应平衡电位,本质上是由电极材料中的锂离子浓度决定的。而锂离子浓度,正好对应SOC。所以OCV-SOC曲线,是电池的“固有指纹”。

关键点: OCV法要求电池必须“静置”。一般磷酸铁锂电池需要静置2小时以上,三元锂也需要至少30分钟。如果电池还在充放电,或者刚停止不久,测出来的电压是极化电压,不是真正的OCV。

4.3.1 OCV-SOC曲线获取

这条曲线怎么来的?通常是在实验室里,用“小电流充放电法”或“间歇放电法”标定出来的。下面是一个典型的OCV-SOC数据表(以磷酸铁锂为例):

SOC (%) OCV (V) 备注
100 3.65 满充状态
90 3.45 平台区开始
80 3.38 平台区
50 3.32 平台区(非常平坦)
20 3.25 平台区结束
10 3.10 快速下降区
5 2.90 接近放电截止
0 2.50 放电截止电压

注意看,磷酸铁锂在20%~80%这个区间,OCV变化非常小,只有不到0.1V。这意味着什么?意味着在这个区间用OCV法估算SOC,精度很差。你想想看,电压测量误差±1mV,对应SOC误差可能达到±5%甚至更多。

我的建议: 三元锂电池的OCV曲线比较陡,用OCV法效果不错。但磷酸铁锂的“平台区”太长了,我建议只在SOC<20%和SOC>80%这两个区间使用OCV法做校准。中间区间,还是靠安时积分+卡尔曼滤波更靠谱。

4.3.2 代码实现(查表法)

// OCV查表法实现(简化版)
// 假设已标定好OCV-SOC表,共N个点
typedef struct {
    float ocv;  // 开路电压 (V)
    float soc;  // 对应的SOC (%)
} OCVTablePoint;

// 线性插值查表
float OCV_To_SOC(float voltage, OCVTablePoint *table, int table_size) {
    // 边界处理
    if (voltage >= table[0].ocv) return table[0].soc;
    if (voltage <= table[table_size-1].ocv) return table[table_size-1].soc;
    
    // 查找区间
    for (int i = 0; i < table_size - 1; i++) {
        if (voltage <= table[i].ocv && voltage > table[i+1].ocv) {
            // 线性插值
            float ratio = (voltage - table[i+1].ocv) / (table[i].ocv - table[i+1].ocv);
            return table[i+1].soc + ratio * (table[i].soc - table[i+1].soc);
        }
    }
    return -1.0f;  // 异常
}

// 使用示例
void OCV_Calibration(AhIntegrator *ah, float measured_voltage) {
    // 假设已定义好ocv_table和TABLE_SIZE
    float soc_from_ocv = OCV_To_SOC(measured_voltage, ocv_table, TABLE_SIZE);
    
    // 当电池静置足够长时间后,用OCV结果修正安时积分的累积误差
    if (battery_is_at_rest()) {
        // 加权融合:OCV结果可信度高时,直接替换
        ah->soc = soc_from_ocv;
        ah->accumulated_ah = soc_from_ocv / 100.0f * ah->capacity;
    }
}

避坑指南: 我曾经遇到过一个问题——电池静置时间不够,测出来的电压不是真正的OCV。结果一查表,SOC显示80%,实际只有60%。后来我加了一个“静置时间判断”逻辑:电压变化率小于0.5mV/min,才认为进入静置状态。这个经验值你可以参考。

4.4 两种方法的工程结合

在实际BMS中,我们不会只用一种方法。典型的做法是:

  1. 上电时: 如果电池静置超过2小时,用OCV法获取初始SOC。否则,用上次下电时保存的SOC。
  2. 运行中: 用安时积分法实时计算SOC变化。
  3. 静置时: 用OCV法校准安时积分的累积误差。
  4. 满充/满放时: 强制校准到100%或0%。

说白了,安时积分法是“主力”,负责日常干活。OCV法是“裁判”,定期检查有没有跑偏。两者配合,才能保证SOC估算的长期精度。

好了,今天的内容就到这里。SOC估算是个大话题,后面我们还会讲卡尔曼滤波、自适应算法这些更高级的东西。但不管多高级的算法,安时积分和开路电压这两个基本功,永远是BMS工程师的“看家本领”。


专注资料整理