3、电流采集与积分算法:霍尔传感器与分流器原理、电流采样时序与同步、安时积分法原理、累积误差分析与修正策略
3.1 霍尔传感器与分流器:两种主流方案
做BMS这么多年,电流采集这块我踩过的坑最多。说白了,电流是电池状态估算的“眼睛”,眼睛要是花了,后面SOC、SOH全是扯淡。
目前主流的电流传感器就两种:霍尔传感器和分流器(也就是锰铜电阻)。
分流器的原理很简单——欧姆定律。在回路里串一个精密电阻,测它两端的电压,I = U / R。优点是线性度极好,温漂可以做到很低,成本也便宜。我在做一款48V低速车BMS时,用的就是分流器方案,精度能做到0.5%以内。
但分流器有个硬伤:它直接串在主回路里,有功率损耗。大电流时发热严重,100A的电流,哪怕用0.1mΩ的电阻,也有1W的发热。而且它和主回路不隔离,采样电路需要做隔离设计。
霍尔传感器就不一样了。它利用霍尔效应,测量电流产生的磁场。非接触式,没有插入损耗,天生隔离。我见过很多同行在高压BMS上首选霍尔方案,因为隔离问题好解决。
不过霍尔传感器也有缺点:温漂大,线性度不如分流器,而且容易受外部磁场干扰。嗯,这里要注意——霍尔传感器在低电流段(比如1A以下)的精度往往很差,因为信号太弱了。
我的选型建议:
- 低压小电流(< 60V,< 100A):优先分流器,精度高、成本低
- 高压大电流(> 400V,> 200A):优先霍尔,隔离方便
- 高精度需求(SOC估算要求高):分流器 + 隔离ADC
3.2 电流采样时序与同步:别让数据“错位”
你想想看,电压和电流的采样如果不同步,算出来的功率、内阻、SOC全是错的。我遇到过最典型的问题:电压在10ms前采的,电流是现在采的,结果算出来的瞬时功率忽高忽低,根本没法用。
采样时序设计的核心原则就一条:电压和电流必须在同一时刻采集。
具体怎么做?
- 使用同步采样ADC(比如ADS131M04),它内部有多路ADC,可以同时触发采样
- 如果MCU只有单路ADC,那就用定时器触发,保证电压和电流的采样间隔固定且极小(< 10μs)
- 采样频率建议100Hz以上,我一般用200Hz,也就是5ms一个点
还有一个容易被忽略的点:PWM噪声同步。如果BMS系统里有DC/DC或者电机控制器,它们的PWM开关会产生巨大的电流纹波。我曾经在一个项目中,采样点正好落在PWM开关的尖峰上,电流值跳得跟心电图似的。
避坑指南:
我曾经在PWM频率为20kHz的系统里,把采样点设置在PWM周期的中间(即开关管导通稳定后),完美避开了开关噪声。具体做法是用MCU的定时器同步PWM的载波信号,在载波波峰或波谷触发采样。
3.3 安时积分法原理:最朴素也最核心
安时积分法,说白了就是“数电子”。
公式很简单:
SOC(t) = SOC(0) - (∫I dt) / Q_max × 100%
其中:
- SOC(0) 是初始荷电状态
- ∫I dt 是累计的放电电量(安时)
- Q_max 是电池最大可用容量
在代码里,我们一般用离散累加来实现积分:
// 安时积分法核心代码
static float soc_integral = 0.0f; // 累计安时数
static float soc_percent = 100.0f; // SOC百分比
void ah_integral_update(float current_A, float dt_s, float q_max_Ah)
{
// 电流为正表示充电,为负表示放电
// dt_s 是采样间隔,单位秒
float dq_Ah = current_A * dt_s / 3600.0f; // 转换为安时
soc_integral += dq_Ah;
// 计算SOC
soc_percent = 100.0f - (soc_integral / q_max_Ah) * 100.0f;
// 限幅
if(soc_percent < 0.0f) soc_percent = 0.0f;
if(soc_percent > 100.0f) soc_percent = 100.0f;
}
代码看着简单,但实际工程里坑不少。比如dt_s怎么取?我习惯用定时器中断来驱动采样,每次中断进来,dt就是固定的(比如5ms)。千万别用while循环里的软件延时,那玩意儿不准。
3.4 累积误差分析与修正策略
安时积分法最大的问题是什么?误差会累积。
你想想看,每次采样都有误差,哪怕只有0.1%,跑上100个循环,误差就变成10%了。我见过一个项目,跑了三个月,SOC显示还有30%,实际电池已经没电了——车直接趴窝在路上。
误差来源主要有三个:
| 误差来源 | 典型大小 | 影响 |
|---|---|---|
| 电流传感器偏置 | ±10mA ~ ±100mA | 长期积分后偏移越来越大 |
| 电流传感器增益误差 | ±0.5% ~ ±2% | 与电流大小成正比 |
| 采样时间误差 | ±0.1% ~ ±1% | 与积分时间成正比 |
| Q_max 标定误差 | ±2% ~ ±5% | 满充/满放时SOC不准 |
怎么修正?我总结了几条实战经验:
- 定期归零:当检测到电池充满(充电截止电压 + 充电电流小于C/20),强制将SOC设为100%。这是最有效的修正手段。
- 满放校准:当电池放电到截止电压且电流很小,强制SOC设为0%。
- 开路电压修正:电池静置一段时间后(我一般等2小时以上),用OCV-SOC查表法修正积分值。注意,磷酸铁锂的OCV曲线太平坦,这个方法不太好用。
- 动态补偿:在电流为0时(系统休眠),检测传感器输出是否归零。如果不归零,记录这个偏置值,在后续积分中减去。
警告:
千万不要在电池大电流充放电时做SOC修正!我见过有人试图在100A放电时用OCV查表修正,结果SOC直接从60%跳到了80%,BMS直接报故障。修正一定要在稳态条件下进行。
最后说一句,安时积分法虽然简单,但做好不容易。我个人习惯是把它和卡尔曼滤波或者扩展卡尔曼滤波结合起来用,用安时积分做短期预测,用电压修正做长期校准。这样既保证了实时性,又解决了累积误差问题。
嗯,电流采集和积分这块,今天就聊到这儿。下一章我们讲电压采集与均衡策略,那又是另一片天地了。