一阶惯性滤波是工业现场处理传感器模拟量(如温度、压力、电流、电压)波动最常用、最有效的数字滤波方法。它计算极轻、资源占用极低,可在PLC、单片机、DCS甚至FPGA中毫秒级实时运行;效果接近硬件RC低通滤波器,但无需额外元件、不老化、参数可在线调节。核心公式:
$$Y_n = a \cdot X_n + (1 - a) \cdot Y_{n-1}$$
其中:
- $X_n$ 是第 $n$ 次采样的原始输入值(例如:AD转换后的12位整数或浮点电压值);
- $Y_n$ 是第 $n$ 次滤波后的输出值(即你最终送入PID控制器、HMI显示或报警判断的值);
- $Y_{n-1}$ 是上一次的滤波输出值(必须保存为变量,不可每次清零);
- $a$ 是滤波系数,取值范围严格限定在 $0 < a \leq 1$。
该公式本质是加权移动平均:新采样值占权重 $a$,历史输出值占权重 $(1-a)$。$a$ 越小,历史值权重越大,响应越慢、平滑度越高;$a$ 越大,新值权重越高,响应越快、但抗扰能力越弱。它不是“去掉噪声”,而是用数学方式让输出“跟不上”快速跳变,从而抑制高频抖动,同时尽量保留真实趋势。
一、为什么必须用它?——模拟量波动的真实危害
工业现场的模拟量信号绝非理想直线。典型干扰源包括:
- 变频器启停产生的共模电压窜入4–20 mA回路;
- 电机碳刷火花、接触器吸合释放引发的微秒级尖峰;
- 长距离敷设时未屏蔽双绞线耦合的工频50 Hz感应电压;
- 热电偶冷端补偿漂移叠加热辐射引起的缓慢漂移;
- 电源纹波导致AD基准电压波动,使所有通道系统性偏移。
若直接将原始 $X_n$ 送入PID控制器:
- 微小抖动被放大为频繁的控制输出修正,导致阀门/变频器反复小幅动作,加速机械磨损;
- 温度显示在±2℃间无规律跳变,操作员无法判断真实趋势,可能误判超温而停机;
- 压力信号毛刺触发虚假高压报警,引发连锁停车。
若采用简单“连续5次取平均”:
- 延迟固定为5个采样周期(如采样间隔100 ms,则延迟500 ms),无法按需调节;
- 无法区分“真实缓慢变化”与“突发噪声”——一个真实上升过程会被强行拉平,丧失响应性;
- 内存需缓存5个历史值,对RAM紧张的8位单片机不友好。
一阶惯性滤波完美规避上述缺陷:仅需1个存储变量($Y_{n-1}$)、2次乘法+1次加法,且滤波强度可精确映射到物理时间常数,实现“该快则快、该慢则慢”。
二、系数 $a$ 的物理意义与工程选型方法
公式中的 $a$ 并非凭经验试凑的“魔法数字”。它与控制系统最关键的动态指标——时间常数 $\tau$——存在严格数学关系:
$$a = 1 - e^{-T/\tau}$$
其中:
- $T$ 是采样周期(单位:秒),例如PLC常规扫描周期为
0.1 s,高速采集卡可能为0.001 s; - $\tau$ 是你期望的等效惯性时间常数(单位:秒),代表输出 $Y_n$ 达到阶跃输入63.2%幅值所需的时间。
✅ 关键结论:只要确定了工艺允许的响应延迟($\tau$)和你的硬件采样能力($T$),$a$ 值就唯一确定,无需反复调试。
实用选型对照表(假设 $T = 0.1\ \text{s}$)
| 期望时间常数 $\tau$ | 计算公式 | $a$ 值(保留4位小数) | 物理效果 |
|---|---|---|---|
| $0.05\ \text{s}$ | $1-e^{-0.1/0.05}$ | 0.8647 |
响应极快,仅抑制极高频毛刺(如开关噪声) |
| $0.2\ \text{s}$ | $1-e^{-0.1/0.2}$ | 0.3935 |
平衡选择,常见于温度、液位控制 |
| $0.5\ \text{s}$ | $1-e^{-0.1/0.5}$ | 0.1813 |
明显平滑,适用于振动环境下的压力、流量信号 |
| $2.0\ \text{s}$ | $1-e^{-0.1/2.0}$ | 0.0488 |
强滤波,用于缓慢变化且噪声严重的场景(如土壤湿度) |
⚠️ 注意:当 $\tau \gg T$(如 $\tau=2.0\ \text{s},\ T=0.1\ \text{s}$),$a$ 会很小(
0.0488)。此时公式中 $(1-a)\approx 0.9512$,计算需保证浮点精度,避免因截断导致 $Y_n$ 趋于停滞。推荐统一使用float或double类型运算,禁用int强制截断。
如何确定你的 $\tau$?
- 查设备手册:热电阻PT100的热响应时间通常标注为“$t_{0.5}=3\ \text{s}$”(上升50%所需时间),对应 $\tau \approx t_{0.5}/0.693 \approx 4.3\ \text{s}$;
- 观察趋势图:在HMI上开启原始信号与滤波后信号同屏曲线,手动调整 $a$ 直至:
- 正常工况下曲线平滑无锯齿;
- 发生真实阶跃(如阀门全开)时,$Y_n$ 在3–5$\tau$内到达95%稳态值(即 $1-e^{-3}\approx 95\%$);
- 保守起步:首次配置建议从 $\tau = 0.5\ \text{s}$ 对应的 $a=0.1813$ 开始测试,再根据现场效果微调。
三、手把手实现步骤(以主流平台为例)
1. 在西门子S7-1200/1500 PLC中(TIA Portal V18+)
前提:已通过AI模块读取通道,原始值存于 DB1.DataRaw(INT类型,范围0–27648对应4–20 mA)。
步骤:
- 声明变量:在数据块
DB1中新增:DataFiltered:REAL,初始值0.0(存储 $Y_{n-1}$);FilterAlpha:REAL,赋值0.1813(即 $a$);
- 编写滤波逻辑(置于主循环OB1中):
// 将原始INT转为REAL便于计算 DB1.DataFiltered := DB1.FilterAlpha * REAL#(DB1.DataRaw) + (1.0 - DB1.FilterAlpha) * DB1.DataFiltered; - 使用滤波值:后续PID指令的
SP_INT或显示控件绑定DB1.DataFiltered,绝不使用DataRaw。
✅ 优势:无需FB封装,纯ST语句,执行时间<10 µs;变量自动保持,断电后
DataFiltered重启为初始值,但可通过“保持性”属性设为断电保持。
2. 在STM32 HAL库(C语言)中
前提:ADC采集完成中断中获得 uint16_t adc_value(0–4095)。
步骤:
- 全局声明:
static float y_prev = 0.0f; // Y_{n-1},static确保跨中断保持 const float alpha = 0.1813f; // a值,定义为const避免重复计算 - 在ADC中断回调中执行:
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) { uint16_t x_n = HAL_ADC_GetValue(hadc); // 获取原始采样X_n float x_n_f = (float)x_n * (3.3f / 4095.0f); // 转为实际电压(V) float y_n = alpha * x_n_f + (1.0f - alpha) * y_prev; // 核心公式 y_prev = y_n; // 更新Y_{n-1}为下次使用 // 后续:y_n可送入PID、UART发送、OLED显示... }
⚠️ 关键细节:
- 必须用
static修饰y_prev,否则每次中断都重置为0;- 乘法用
float运算,禁止int运算后强转(如(int)(alpha*x)会丢失精度);- 若资源极端受限,可用定点算法(如Q15格式),但需重写公式为整数移位运算,此处不展开。
3. 在Python(上位机数据后处理)中
前提:raw_data 是长度为N的NumPy数组,含原始采集值。
步骤:
import numpy as np
def first_order_filter(data, alpha):
"""一阶惯性滤波向量化实现"""
filtered = np.empty_like(data, dtype=float)
filtered[0] = data[0] # 首点直接赋值,避免无Y_{-1}
for i in range(1, len(data)):
filtered[i] = alpha * data[i] + (1 - alpha) * filtered[i-1]
return filtered
# 使用示例:
raw_data = np.array([25.1, 25.3, 24.9, 28.7, 25.2, 25.0, ...]) # 含毛刺的温度序列
clean_data = first_order_filter(raw_data, alpha=0.2)
✅ 进阶技巧:利用NumPy的
np.convolve实现向量化(免循环),但需注意边界处理,初学者建议先用循环确保逻辑正确。
四、避坑指南:90%工程师踩过的5个错误
| 错误现象 | 根本原因 | 正确做法 |
|---|---|---|
| 滤波后信号完全不动,始终等于初始值 | Y_{n-1} 未保存为静态/全局变量,每次计算都用 0 代入 |
检查变量作用域,确保 Y_{n-1} 生命周期覆盖连续采样周期 |
| 滤波后信号缓慢爬升/下降,永不收敛 | 公式误写为 Y_n = a*X_n + (1+a)*Y_{n-1}(1+a >1),导致指数发散 |
严格核对公式:1-a 必须为正数且小于1;用计算器验证 a=0.2 时 1-a=0.8 |
| HMI显示仍剧烈跳变,滤波无效 | 滤波值 Y_n 未真正送入显示控件,仍在绑定原始 X_n 地址 |
在HMI变量连接界面,100%确认绑定路径指向滤波后变量(如 DB1.DataFiltered 而非 DB1.DataRaw) |
| 调节 $a$ 后效果相反:$a$ 越大越抖,越小越平 | 混淆了 $a$ 的物理意义,误以为 $a$ 是“平滑系数”而非“新鲜度系数” | 牢记口诀:“$a$ 大跟得紧,$a$ 小拖得稳”;实测时用阶跃输入(如突然改变传感器温度)观察响应速度 |
| PLC下载后滤波失效,重启又正常 | Y_{n-1} 变量未设置“保持性”,断电后复位为0,首次计算 Y_1 = a*X_1 + (1-a)*0 = a*X_1,大幅衰减 |
在TIA Portal中右键变量 → 属性 → “保持性”勾选;或初始化为合理预估值(如 Y_{n-1}=25.0) |
五、进阶应用:多级串联与自适应 $a$
▶ 多级串联提升滤波深度
单级滤波的幅频特性是-20 dB/十倍频程衰减。若需更强抑制(如消除50 Hz工频干扰),可串联两级相同参数滤波器:
- 第一级输出 $Y^{(1)}_n = a \cdot X_n + (1-a) \cdot Y^{(1)}_{n-1}$;
- 第二级输入为 $Y^{(1)}_n$,输出 $Y^{(2)}_n = a \cdot Y^{(1)}_n + (1-a) \cdot Y^{(2)}_{n-1}$。
等效时间常数变为 $\tau_{eq} = 2\tau$,但计算量翻倍,仅在噪声极其恶劣时启用。
▶ 自适应 $a$ 应对工况突变
某些场景(如锅炉点火初期)需要快速响应,稳定后需强平滑。可设计 $a$ 动态调整逻辑:
- 实时计算相邻采样差值绝对值
delta = |X_n - X_{n-1}|; - 当
delta > threshold(如温度突变2℃/s),临时增大 $a$ 至0.5,加快跟踪; - 否则恢复常规 $a=0.18$。
此方案需谨慎,避免因噪声触发误切换。
六、与其它滤波方法对比(核心结论)
| 方法 | 计算量 | 延迟 | 平滑效果 | 参数物理意义 | 适用场景 |
|---|---|---|---|---|---|
| 一阶惯性滤波 | ★☆☆☆☆(极低) | 可调(由 $\tau$ 决定) | 优秀(指数衰减) | 明确(时间常数 $\tau$) | 绝大多数工业模拟量 |
| 中值滤波 | ★★★☆☆(需排序) | 固定(窗口一半) | 对脉冲噪声极佳,但平滑连续波动差 | 窗口长度(无时间概念) | 数字量开关抖动、短时尖峰 |
| 卡尔曼滤波 | ★★★★★(矩阵运算) | 最小理论延迟 | 最优估计,需精确建模 | 噪声协方差矩阵(难标定) | 高端导航、目标跟踪 |
| 移动平均(MA) | ★★☆☆☆(累加+除法) | 固定(窗口长度×T) | 矩形窗频谱泄漏严重 | 窗口点数(无物理时间) | 教学演示、对延迟不敏感场合 |
✅ 终极建议:把一阶惯性滤波作为模拟量处理的第一道、也是最后一道防线。 先用它解决95%的问题;只有在其无法满足时(如需分离特定频率成分),再考虑FFT或带通滤波等复杂方案。
七、实测案例:某化工厂反应釜温度控制优化
问题:Pt100温度信号经2 km屏蔽电缆接入PLC,原始曲线呈密集锯齿状(±1.5℃),导致温度PID输出频繁震荡,搅拌电机电流波动超标。
实施:
- 采样周期 $T = 0.2\ \text{s}$(PLC默认);
- Pt100手册标明 $t_{0.5}=4.5\ \text{s}$ → $\tau \approx 6.5\ \text{s}$;
- 计算 $a = 1 - e^{-0.2/6.5} = 0.0303$;
- 在TIA Portal中添加滤波逻辑,绑定至PID设定值通道。
效果:
- 滤波后温度曲线平滑如绸缎,波动<±0.2℃;
- PID输出电流稳定,电机轴承温升下降12℃;
- 系统响应时间(从设定值变化到95%稳态)为 $3\tau = 19.5\ \text{s}$,完全满足工艺要求。
初始化 $Y_{n-1}$ 时,若已知传感器典型工作值,将其设为初始值可消除启动瞬态;否则设为首次采样值 $X_0$。

暂无评论,快来抢沙发吧!