3、被动均衡控制策略:固定阈值法、动态阈值法
聊到被动均衡,很多刚入行的朋友第一反应就是「电阻放电」。嗯,没错,原理确实简单——把电压高的电池多余能量通过电阻以热量形式消耗掉。但控制策略怎么定,这里头门道不少。
我个人习惯把被动均衡策略分成两大类:固定阈值法和动态阈值法。今天咱们就掰开揉碎了聊聊这两种方法。
3.1 固定阈值法
固定阈值法,说白了就是设定一个电压门限。比如我设定3.65V,只要某节电池电压超过这个值,均衡电路就启动,给它放电。
你想想看,这方法是不是特别直观?代码写起来也简单:
// 固定阈值均衡示例
#define BALANCE_THRESHOLD 3.65f // 均衡阈值
#define HYSTERESIS_VOLT 0.02f // 迟滞电压
void balance_fixed_threshold(BatteryCell *cells, uint8_t num_cells) {
for (uint8_t i = 0; i < num_cells; i++) {
if (cells[i].voltage > BALANCE_THRESHOLD) {
// 开启均衡
cells[i].balance_on = 1;
} else if (cells[i].voltage < (BALANCE_THRESHOLD - HYSTERESIS_VOLT)) {
// 关闭均衡
cells[i].balance_on = 0;
}
// 在阈值附近保持原状态,避免频繁开关
}
}
这里我加了个迟滞电压,为什么?因为电池电压在均衡开启瞬间会有一个跌落,如果没有迟滞,均衡会在阈值附近反复开关——这在项目里可是个大坑。
我曾经在一个储能项目里吃过这个亏。当时没加迟滞,均衡MOS管在阈值附近以几十赫兹的频率开关,不到半小时MOS管就过热烧了。从那以后,我所有均衡代码里迟滞电压都是标配。
固定阈值法的优点很明显:
- 实现简单——几行代码搞定,调试也方便
- 计算量小——MCU几乎零负担
- 行为可预测——什么时候均衡、什么时候停止,一目了然
但缺点同样突出:
- 阈值难选——设高了均衡效果差,设低了频繁启动
- 适应性差——不同温度、不同老化程度的电池,最优阈值不一样
- 容易过度均衡——特别是电池组内阻不一致时
3.2 动态阈值法
动态阈值法就聪明多了。它不设死板的固定值,而是根据电池组的实时状态动态调整均衡阈值。
我常用的动态阈值策略有两种:
3.2.1 基于平均电压的动态阈值
这种方法以电池组平均电压为基准,设定一个偏移量。比如:
// 基于平均电压的动态阈值均衡
void balance_dynamic_average(BatteryCell *cells, uint8_t num_cells) {
float avg_voltage = 0.0f;
float threshold_offset = 0.02f; // 偏移量,可调
// 计算平均电压
for (uint8_t i = 0; i < num_cells; i++) {
avg_voltage += cells[i].voltage;
}
avg_voltage /= num_cells;
// 动态阈值 = 平均电压 + 偏移量
float dynamic_threshold = avg_voltage + threshold_offset;
for (uint8_t i = 0; i < num_cells; i++) {
if (cells[i].voltage > dynamic_threshold) {
cells[i].balance_on = 1;
} else {
cells[i].balance_on = 0;
}
}
}
这个方法的好处是:电池组整体电压高时,阈值自动抬高;整体电压低时,阈值自动降低。说白了就是跟着大部队走。
偏移量的选取很关键。我一般取电池单体电压标准差的1.5~2倍。太小了均衡频繁,太大了效果不明显。这个参数建议在实验室里用实际电池组标定一下。
3.2.2 基于SOC的动态阈值
这个方法更精细一些。它用SOC代替电压作为均衡依据,因为SOC更能反映电池的真实状态。
// 基于SOC的动态阈值均衡
void balance_dynamic_soc(BatteryCell *cells, uint8_t num_cells) {
float soc_threshold = 5.0f; // SOC差异阈值,单位%
// 找到最高和最低SOC
float soc_max = cells[0].soc;
float soc_min = cells[0].soc;
for (uint8_t i = 1; i < num_cells; i++) {
if (cells[i].soc > soc_max) soc_max = cells[i].soc;
if (cells[i].soc < soc_min) soc_min = cells[i].soc;
}
// 如果SOC差异超过阈值,启动均衡
if ((soc_max - soc_min) > soc_threshold) {
for (uint8_t i = 0; i < num_cells; i++) {
// 只均衡SOC最高的那几节
if (cells[i].soc > (soc_max - soc_threshold / 2)) {
cells[i].balance_on = 1;
} else {
cells[i].balance_on = 0;
}
}
} else {
// 差异不大,不均衡
for (uint8_t i = 0; i < num_cells; i++) {
cells[i].balance_on = 0;
}
}
}
这里要注意,SOC的精度直接影响均衡效果。如果SOC估算误差超过5%,那这个方法基本就废了。
动态阈值法的本质是「让均衡阈值跟着电池状态走」。固定阈值法像是一个死板的门卫,超过线就拦;动态阈值法像是一个灵活的交警,根据路况动态调整。
3.3 两种方法的对比
| 对比项 | 固定阈值法 | 动态阈值法 |
|---|---|---|
| 实现复杂度 | 低 | 中 |
| 计算资源消耗 | 极低 | 低~中 |
| 适应性 | 差 | 好 |
| 均衡效果 | 一般 | 较好 |
| 调试难度 | 低 | 中 |
| 适用场景 | 小容量、低串数电池组 | 大容量、高串数电池组 |
我个人建议:产品初期用固定阈值法快速验证,后期再切换到动态阈值法优化性能。别一上来就搞复杂的动态算法,万一SOC估算不准,均衡效果反而更差。
3.4 实际项目中的选择建议
我在几个量产项目里总结了一些经验:
- 电动工具电池包(4~10串):固定阈值法就够了,成本低、代码简单
- 电动自行车电池组(13~20串):建议用基于平均电压的动态阈值法
- 储能系统(几十到几百串):必须用基于SOC的动态阈值法,而且要配合温度补偿
嗯,这里还要提醒一点:无论用哪种方法,均衡电流都不能太大。被动均衡的本质是发热,电流大了散热跟不上,电池温度飙升,轻则影响寿命,重则引发安全事故。
我记得有个项目,客户非要追求均衡速度,把均衡电流设到了2A。结果电池温度从25℃飙到65℃,吓得我赶紧把电流降回0.5A。所以啊,均衡这事,慢就是快。
下一章咱们聊聊主动均衡,那又是另一番天地了。