第1章:温度采集与滤波——NTC/PTC原理、ADC采样、滑动平均滤波、卡尔曼滤波入门
大家好,我是老张。在BMS这个行当摸爬滚打了十几年,要说最基础也最要命的一环,就是温度采集。你想想看,电池包里的电芯要是温度测不准,热管理策略就是瞎指挥,轻则续航打折,重则热失控。今天咱们就来聊聊温度采集与滤波的那些事儿。
1.1 NTC与PTC:温度传感器的选型逻辑
先说传感器。BMS里用的最多的就是NTC(负温度系数热敏电阻)。说白了,温度越高,电阻值越小。PTC(正温度系数)刚好反过来,温度越高电阻越大。我个人习惯在电池模组里用NTC,因为它在常温段灵敏度高,适合我们关心的-20℃到60℃这个区间。
NTC的关键参数:
- B值(材料常数): 一般在3000-4500K之间。B值越大,温度变化时电阻变化越剧烈。我建议选B=3950的,这是行业主流,互换性好。
- R25(25℃时的标称电阻): 常用10kΩ或100kΩ。10kΩ的功耗小,适合电池包这种对自热敏感的场景。
- 精度: 1%还是5%?别省这个钱。我在项目里吃过亏,用了5%的NTC,结果同一温度下不同电芯读数差了2℃多,均衡算法直接乱套。
避坑指南: 我曾经遇到过NTC引线过长导致测量偏差的问题。线阻每增加1Ω,在低温区可能引入0.5℃的误差。所以,要么用四线制接法,要么在软件里做线阻补偿。
1.2 ADC采样:从模拟到数字的桥梁
NTC的电阻变化是模拟信号,MCU只认数字。所以中间需要ADC(模数转换器)。BMS里常用的ADC分辨率是12位或16位。12位能分辨4096个等级,16位是65536个。你想想看,对于0-100℃的范围,12位ADC的理论分辨率是0.024℃,够用了。但实际噪声会把这个精度吃掉不少。
ADC采样的关键点:
- 参考电压: 内部参考还是外部参考?我建议用外部精密参考(比如2.5V或3.3V),内部参考温漂太大,夏天和冬天能差出几十个LSB。
- 采样时间: ADC内部有个采样电容,需要时间充电。采样时间太短,电容没充满,读数偏小。我一般设成10μs以上,具体看MCU手册。
- 过采样: 简单粗暴但有效。比如采64次取平均,等效分辨率能提高3位。代价是采样时间变长,但BMS对实时性要求没那么苛刻。
我的小技巧: 在ADC输入端并联一个0.1μF的电容,能滤掉大部分高频噪声。别小看这个电容,它救过我好几次项目。
1.3 滑动平均滤波:简单实用的降噪利器
ADC采回来的数据,直接拿去用?别急,噪声大得很。最简单的滤波就是滑动平均。维护一个长度为N的队列,每次新数据进来,扔掉最老的,算一下队列平均值。
// 滑动平均滤波示例(C语言伪代码)
#define FILTER_LEN 8
float buffer[FILTER_LEN] = {0};
int index = 0;
float sum = 0;
float sliding_average(float new_sample) {
sum -= buffer[index]; // 减去最老的数据
buffer[index] = new_sample; // 存入新数据
sum += new_sample; // 加上新数据
index = (index + 1) % FILTER_LEN;
return sum / FILTER_LEN;
}
N取多少合适?我一般取8或16。N太小,滤波效果差;N太大,响应变慢。比如电池包突然从25℃升到30℃,N=16的滤波可能要等好几秒才能跟上。嗯,这里要注意:滑动平均对周期性噪声(比如50Hz工频干扰)效果很好,但对突发性尖峰脉冲,它只能削弱,不能完全消除。
1.4 卡尔曼滤波入门:从“猜”到“准”
滑动平均虽然简单,但不够聪明。卡尔曼滤波就不一样了,它会根据模型“预测”下一个温度值,然后用实际测量值去修正预测。说白了,就是一边猜一边改,越猜越准。
卡尔曼滤波的核心思想:
- 预测: 根据上一时刻的状态,估计当前时刻的状态。比如温度不会突变,所以预测值≈上一时刻的滤波值。
- 更新: 用当前测量值去修正预测值。修正的力度取决于“卡尔曼增益”——测量越可靠,增益越大;预测越可靠,增益越小。
对于温度这种变化缓慢的量,卡尔曼滤波的模型可以简化:
// 一维卡尔曼滤波(温度场景简化版)
float x_hat = 25.0; // 初始估计值(比如室温)
float P = 1.0; // 估计误差协方差
float Q = 0.01; // 过程噪声(模型不确定性)
float R = 0.1; // 测量噪声(传感器精度)
float kalman_filter(float z) {
// 预测
float x_pred = x_hat; // 温度变化慢,预测值≈上一时刻
float P_pred = P + Q; // 预测误差增大
// 更新
float K = P_pred / (P_pred + R); // 卡尔曼增益
x_hat = x_pred + K * (z - x_pred); // 修正估计
P = (1 - K) * P_pred; // 更新误差
return x_hat;
}
你看,代码比滑动平均长不了多少,但效果天差地别。卡尔曼滤波能自适应地调整滤波强度:当测量值噪声大时,它更相信预测;当测量值稳定时,它快速跟踪真实值。
注意: 卡尔曼滤波不是万能的。它假设噪声是高斯分布,如果实际噪声不是这样(比如有突发干扰),效果会打折扣。我建议在卡尔曼滤波之前,先做一次简单的限幅滤波,把明显异常的点剔除掉。
1.5 知识体系总览
为了让你更直观地理解本章的知识结构,我画了一张图:
1.6 实战建议:三种滤波怎么选?
讲了这么多,你可能会问:到底用哪种滤波?我根据经验给你一个参考:
| 场景 | 推荐滤波方式 | 理由 |
|---|---|---|
| 电池包正常工况 | 滑动平均(N=8) | 计算量小,效果够用 |
| 快充/大倍率放电 | 卡尔曼滤波 | 温度变化快,需要快速跟踪 |
| 传感器老化/噪声大 | 卡尔曼滤波 + 限幅 | 自适应性强,能抑制异常值 |
| 资源受限的MCU | 滑动平均 | 不占内存,不耗算力 |
我的经验: 别把滤波搞得太复杂。我见过有人用卡尔曼滤波调了两个月参数,最后发现滑动平均加个中值滤波效果差不多。先跑通,再优化,这是铁律。
好了,温度采集与滤波的基础就聊到这儿。记住:传感器是眼睛,ADC是神经,滤波是大脑。三者配合好了,你的BMS才算有了“感觉”。
公众号:蓝海资料掘金营,微信deep3321