嵌入式常用算法之低通滤波算法
原理
一阶滤波,又叫一阶惯性滤波,或一阶低通滤波,软件实现RC低通滤波器的功能。
作用:
一阶低通滤波法采用本次采样值与上次滤波输出值进行加权,得到有效滤波值,使得输出对输入有反馈作用。
公式
Y(n)=αX(n)+(1−α)Y(n−1)
其中:α=滤波系数;X(n)=本次采样值;Y(n-1)=上次滤波输出值;Y(n)=本次滤波输出值。
特点:
-
对于周期干扰有良好的抑制作用,比如采样电池电压,对于干扰电压瞬时突变有很好过滤效果;
-
带来了相位滞后,导致灵敏度低(缺);
不能滤除频率高于采样频率的二分之一(称为奈奎斯特频率)的干扰(例如采样频率为100Hz,则它不能滤除50Hz以上的干扰信号)(缺);
滤波系数越小,滤波结果越平稳,灵敏度越低;
滤波系数越大,灵敏度越高,但滤波结果越不稳定;
一阶滤波无法完美地兼顾灵敏度和平稳度。有时,我们只能寻找一个平衡,在可接受的灵敏度范围内取得尽可能好的平稳度。而在一些场合,我们希望拥有这样一种接近理想状态的滤波算法。即:当数据快速变化时,滤波结果能及时跟进(灵敏度优先);当数据趋于稳定,在一个固定的点上下振荡时,滤波结果能趋于平稳(平稳度优先)。
-
来源:一阶RC低通滤波算法原理与实现_rc 采样函数-CSDN博客
应用场景:
比如
ADC采集,有时会因为电路的噪声,在一瞬间出现电压的变大(小),为了过滤这类型的干扰,可以尝试采用低通滤波算法解决;
编码器数据采集,比如采用光电编码器,启动4倍频,这个倍频数据容易被干扰。由于干扰是瞬时等待,可以采用低通滤波算法
算法代码如下:
#include <stdio.h>
#define a 0.2
float lowPassFilter(float input) {
// 静态变量,用于保存上一次滤波后的值
static float previousFilteredValue = 0.0;
// 根据采样系数计算滤波后的值
float filteredValue = a * input +(1-a)* previousFilteredValue;
// 更新历史滤波后的值
previousFilteredValue = filteredValue;
// 返回本次滤波后的值
return filteredValue;
}
弄一个数据测试一下
#include <stdio.h>
#define a 0.2
float lowPassFilter(float input) {
// 静态变量,用于保存上一次滤波后的值
static float previousFilteredValue = 0.0;
// 根据采样系数计算滤波后的值
float filteredValue = a * input +(1-a)* previousFilteredValue;
// 更新历史滤波后的值
previousFilteredValue = filteredValue;
// 返回本次滤波后的值
return filteredValue;
}
int main() {
float inputValues[] = {11,12,13,14,13,12,11,13,14,11,10,10.2, 11.5, 10.8, 99.1, 11.3,1.3,11.3};
int numValues = sizeof(inputValues) / sizeof(inputValues[0]);
for (int i = 0; i < numValues; i++) {
float filteredValue = lowPassFilter(inputValues[i]);
// 打印输入值和对应的滤波后的值
printf("Filtered value for input %f is %f\n", inputValues[i], filteredValue);
}
return 0;
}
参考文章:
一阶RC低通滤波算法原理与实现_rc 采样函数-CSDN博客
算法学习笔记之一阶低通滤波算法_一阶低通滤波公式-CSDN博客
https://patents.google.com/patent/CN107425759A/zh