4. BMS核心算法模块规范:SOC估算算法规范
说到BMS的核心,SOC估算绝对是绕不开的硬骨头。我个人习惯把SOC比作电池的「油表」,但这个油表可比汽车油箱复杂多了。你想想看,油箱里的油是静止的,而电池里的电荷是动态的,还受温度、老化、充放电倍率影响。今天我就把安时积分法和卡尔曼滤波这两种主流方案掰开揉碎了讲。
4.1 安时积分法:最朴素的方案
安时积分法,说白了就是「电流对时间做积分」。公式很简单:
SOC(t) = SOC(0) - (∫I·dt) / Q_max × 100%
其中I是电流(放电为正),Q_max是电池最大可用容量。我在项目中遇到过一个问题:初始SOC不准,后面全盘皆输。所以安时积分法的核心痛点有两个:
- 初始值校准:每次上电必须通过OCV(开路电压)查表得到初始SOC
- 累积误差:电流采样误差会随时间累积,必须定期修正
代码实现上,我建议用定点数运算代替浮点数,避免MCU资源浪费:
// 安时积分核心函数
int32_t soc_ah_integrate(int32_t current_mA, uint32_t dt_ms, int32_t soc_q16) {
// Q16格式:SOC = soc_q16 / 65536 * 100%
int32_t delta_soc;
// 电流积分:delta_soc = (current_mA * dt_ms) / (Q_max_mAh * 3600)
delta_soc = (int64_t)current_mA * dt_ms * 100 / (Q_MAX_MAH * 3600);
soc_q16 -= delta_soc; // 放电为负
// 限幅保护
if (soc_q16 < 0) soc_q16 = 0;
if (soc_q16 > 65536) soc_q16 = 65536;
return soc_q16;
}
4.2 卡尔曼滤波:进阶玩家的选择
卡尔曼滤波,嗯,这名字听起来高大上,其实核心思想就一句话:用「预测+测量」不断修正。我刚开始学的时候也觉得难,后来发现把它拆成三步就简单了:
- 预测阶段:用安时积分法预测下一时刻的SOC
- 测量阶段:用电压模型反推SOC(通过OCV曲线)
- 更新阶段:根据预测和测量的误差,动态调整权重
为什么要用卡尔曼滤波?因为安时积分法怕累积误差,而电压法怕动态工况不准。两者互补,卡尔曼滤波就是那个「和事佬」。
核心公式(离散卡尔曼滤波):
// 预测
x_pred = A * x_est + B * u
P_pred = A * P_est * A^T + Q
// 更新
K = P_pred * H^T * (H * P_pred * H^T + R)^(-1)
x_est = x_pred + K * (z - H * x_pred)
P_est = (I - K * H) * P_pred
这里Q是过程噪声协方差,R是测量噪声协方差。我建议Q取0.01,R取0.1,这是我在多个项目中试出来的经验值。当然,具体值要根据电池特性微调。
💡 我的个人习惯: 卡尔曼滤波的初始化很关键。我一般先跑10秒的安时积分,等状态稳定了再启动卡尔曼滤波。否则初始协方差矩阵P设不对,滤波会发散。
4.3 SOH估算算法规范
SOH(健康状态)估算,说白了就是回答「这电池还能用多久?」。我常用的方法有两种:
| 方法 | 原理 | 适用场景 | 精度 |
|---|---|---|---|
| 容量衰减法 | SOH = Q_current / Q_initial × 100% | 长期在线监测 | ±3% |
| 内阻增长法 | SOH = (R_eol - R_current) / (R_eol - R_initial) × 100% | 离线诊断 | ±5% |
容量衰减法最直观,但需要完整的充放电周期才能计算。内阻增长法可以实时估算,但内阻测量受温度影响大。我建议两者结合:平时用内阻法做趋势判断,每50个完整周期用容量法做一次校准。
⚠ 我曾经犯过的错: 某次项目只用了容量法,结果用户经常浅充浅放,SOH半年都没更新。后来我加了强制深放策略:如果连续30天没有完整周期,就自动执行一次0.5C恒流放电到截止电压。
4.4 SOE估算算法规范
SOE(能量状态)估算,很多人把它和SOC搞混。区别在哪?SOC看的是「电量」,SOE看的是「还能做多少功」。公式如下:
SOE = (剩余能量) / (最大可用能量) × 100%
剩余能量 = ∫(V_ocv - I * R) * I * dt
这里V_ocv是开路电压,R是内阻。你想想看,同样50%的SOC,大倍率放电时内阻压降大,实际能放出的能量更少。所以SOE比SOC更能反映真实续航。
我建议SOE的更新频率设为1Hz,比SOC的10Hz慢一些。因为能量计算需要电压和电流的乘积,噪声比较大,滤波时间常数建议设为5秒。
💡 避坑指南: 我曾经在低温环境下发现SOE跳变严重。后来排查发现是内阻R随温度变化没补偿。解决方案是建立R-T(内阻-温度)二维查表,每5℃一个插值点。
4.5 三种算法的协同工作
在实际BMS中,SOC、SOH、SOE不是孤立的。我画个简单的逻辑关系:
- SOC → SOH:SOC的累积充放电量用于计算SOH的容量衰减
- SOH → SOC:SOH中的Q_max用于安时积分的分母
- SOC + SOH → SOE:SOE需要SOC和SOH中的内阻参数
嗯,这里要注意:三个算法的更新周期要错开。我一般这样安排:
| 算法 | 更新周期 | 触发条件 |
|---|---|---|
| SOC(安时积分) | 100ms | 持续运行 |
| SOC(卡尔曼滤波) | 1s | 电流变化率 < 5A/s |
| SOH | 1天 | 完成完整充放电 |
| SOE | 1s | 持续运行 |
最后说一句:算法再牛,也怕硬件不给力。我建议电流采样用24位ADC,电压采样用16位ADC,温度采样用NTC加线性化电路。这些细节,往往决定了你的SOC精度是1%还是5%。