10种常用滤波算法特点及例程

1. 限幅滤波法

(1)原理

通过给定的最大偏差值A来实现,如果本次值与上次差值<=A,则本次有效;否则无效,使用上次值代替。

(2)特点

  • 优点:能有效克服偶然因素导致的脉冲干扰
  • 缺点:无法抑制周期性干扰,平滑性差

(3)例程

int Filter_Value;
int Value;

// 限幅滤波法(又称程序判断滤波法)
#define FILTER_A 1
int Filter() {
  int NewValue;
  NewValue = Get_AD();
  if(((NewValue - Value) > FILTER_A) || ((Value - NewValue) > FILTER_A))
    return Value;
  else
    return NewValue;
}

2. 中位值滤波法

(1)原理

连续采集N次值(N为奇数),将采样值按大小排列,取中间值为本次有效值

(2)特点

  • 优点:能有效克服偶然因素导致的波动干扰,对温度等变换缓慢的被测参数有良好滤波效果
  • 缺点:不适合待测量快速变换的场合,如流量、速度等

(3)例程

int Filter_Value;

// 中位值滤波法
#define FILTER_N 101
int Filter() {
  int filter_buf[FILTER_N];
  int i, j;
  int filter_temp;
  for(i = 0; i < FILTER_N; i++) {
    filter_buf[i] = Get_AD();
    delay(1);
  }
  // 采样值从小到大排列(冒泡法)
  for(j = 0; j < FILTER_N - 1; j++) {
    for(i = 0; i < FILTER_N - 1 - j; i++) {
      if(filter_buf[i] > filter_buf[i + 1]) {
        filter_temp = filter_buf[i];
        filter_buf[i] = filter_buf[i + 1];
        filter_buf[i + 1] = filter_temp;
      }
    }
  }
  return filter_buf[(FILTER_N - 1) / 2];
}

3. 算术平均滤波法

(1)原理

连续采用N个值进行算数平均运算

(2)说明

  • N值较大时:信号平滑度较高,但灵敏度较低;

  • N值较小时:信号平滑度较低,但灵敏度较高;

  • N值的选取:一般流量,N=12;压力:N=4

(3)特点

  • 优点:适合对一般具有随机干扰的信号(即信号在某一数据范围附近上下波动)进行滤波
  • 缺点:不适合待测量变换较快或要求数据计算速度较快的实时控制,较浪费RAM

(4)例程

int Filter_Value;
// 算术平均滤波法
#define FILTER_N 12
int Filter() {
  int i;
  int filter_sum = 0;
  for(i = 0; i < FILTER_N; i++) {
    filter_sum += Get_AD();
    delay(1);
  }
  return (int)(filter_sum / FILTER_N);
}

4. 递推平均滤波法

(1)原理

把连续N个采样值看成一个队列,队列长度固定为N,每次采样把新数据放入队尾,并扔掉队首的一次数据,把队列中的N个数据进行平均计算,即获得新的滤波值

(2)特点

  • 优点:对周期性干扰具有良好的抑制作用,平滑度高,适合高频振荡系统;
  • 缺点:对偶然出现的脉冲性干扰的抑制作用较差,不适于脉冲干扰较严重的场合,不适于开关电源电路。

(3)例程

#define N 12

char value_buf[N];
char i = 0;

char filter(void) {
    char count = 0;
    int sum = 0;

    value_buf[i++] = get_ad();
    if(i == N) {
        i = 0;    //先进先出
    }
    for(count = 0; count < N; count++) {
        sum += value_buf[count];
    }
    return (char)(sum / N);
}

5. 中位值平均滤波法

(1)原理

采一组队列去掉最大值和最小值

(2)特点

  • 优点:融合了两种滤波的优点。对于偶然出现的脉冲性干扰,可消除有其引起的采样值偏差,对周期干扰有良好的抑制作用,平滑度高,适于高频振荡的系统;
  • 缺点:测量速度慢;

(3)例程

#define N 12

char filter(void) {
    char i = 0, j = 0, temp = 0;
    char value_buf[N];
    int sum = 0;

    for(i = 0; i < N; i++){
        value_buf[i] = get_ad();
        delay();
    }

    for(j = 0; j < N - 1; j++) {
        for(i = 0; i < N - j; i++) {
            if(value_buf[i] > value_buf[i + 1]) {
                temp = value_buf[i];
                value_buf[i] = value_buf[i + 1];
                value_buf[i + 1] = temp;
            }
        }
    }
    for(i = 1; i < N - 1; i++) {
        sum += value_buf[i];
    }
    return (char)(sum / (N - 2));
}

6. 限幅平均滤波法

(1)原理

限幅+平均

(2)特点

  • 优点:融合了两种滤波法的优点,对于偶然出现的脉冲性干扰,可消除有其引起的采样值偏差;
  • 缺点:较浪费RAM

(3)例程

7. 加权递推平均滤波法

(1)原理

对递推平均滤波法的改进,即不同时刻的数据加以不同权值;通常是越接近现时刻的数据,权值越大,新采样值的权重越大,则灵敏度越高,但信号平滑度越低。

(2)特点

  • 优点:适用于有较大纯滞后时间常数的对象,和采样周期较短的系统;
  • 缺点:对于纯滞后时间常数较小、采样周期较长、变化缓慢的信号;不能迅速反应系统当前所受干扰的严重程度,滤波效果差。

(3)例程

/* coe数组为加权系数表 */
#define N 12

char coe[N] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};

char sum_coe = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12;

char filter(void) {
    char i = 0;
    char value_buf[N];
    int sum = 0;

    for(i = 0; i < N; i++) {
        value_buf[i] = get_ad();
        delay();
    }
    for(i = 0; i < N; i++) {
        sum += value_buf[i] * coe[i];
    }
    return (char)(sum / sum_coe);
}

8. 消抖滤波法

(1)原理

  • 设置一个滤波计数器,将每次采样值与当前有效值比较;
  • 如果采样值=当前有效值,计数器清零;
  • 如果不相等,则计数器+1,并判断计数器是否溢出;
  • 如果计数器溢出,则将本次值替换当前有效值,并清零计数器;

(2)特点

  • 优点:对待测量缓慢变化的参数有较好滤波效果,可避免在临界值附近控制器的反复开关跳动或者显示器上数字抖动;
  • 缺点:不适于快速变化的参数测量,如果计数器溢出的采样恰好是干扰值,则会将干扰值当做有效值引入系统;

(3)例程

#define N 12

char filter(void) {
    char i = 0;
    char new_value = 0, value = 0;

    new_value = get_ad();

    while(value != new_value) {
        i++;
        if(i > N) {
            return new_value;
        }
        delay();
        new_value = get_ad();
    }
    return value;
}

9. 限幅消抖滤波法

(1)原理

相当于“限幅滤波法”+“消抖滤波法”;

先限幅,后消抖。

(2)特点

  • 优点:继承了“限幅”和“消抖”的优点,改进了“消抖滤波法”中的某些缺陷,避免将干扰值导入系统;
  • 缺点:不适合待测量变换快速的场合

(3)例程

int Filter_Value;
int Value;

// 限幅消抖滤波法
#define FILTER_A 1
#define FILTER_N 5
int i = 0;
int Filter() {
  int NewValue;
  int new_value;
  NewValue = Get_AD();
  if(((NewValue - Value) > FILTER_A) || ((Value - NewValue) > FILTER_A))
    new_value = Value;
  else
    new_value = NewValue;
  if(Value != new_value) {
    i++;
    if(i > FILTER_N) {
      i = 0;
      Value = new_value;
    }
  }
  else
    i = 0;
  return Value;
}

10. 一阶滞后滤波法

(1)原理

α = ( 0 , 1 ) α=(0,1) α=(0,1) f i l t e r d a t a = ( 1 − α ) 本 次 采 样 值 + α 上 次 滤 波 结 果 filter_{data} = (1-\alpha)本次采样值+\alpha 上次滤波结果 filterdata=(1α)+α

(2)特点

  • 优点:对周期性干扰具有良好的抑制作用,适合波动频率较高的场合;
  • 缺点:有相位滞后,灵敏度低,滞后程度取决于α的值,不能消除滤波频率高于采样频率1/2的干扰信号

(3)例程

int Filter_Value;
int Value;

// 一阶滞后滤波法
#define FILTER_A 0.01
int Filter() {
  int NewValue;
  NewValue = Get_AD();
  Value = (int)((float)NewValue * FILTER_A + (1.0 - FILTER_A) * (float)Value);
  return Value;
}

本文转自临远科技-熊冰乎文​五大滤波算法原理、场景及实践及嵌入式基地乎文常见的滤波算法(C语言),侵权请联系

1、限幅滤波(又称程序判断滤波) A、方: 根据经验判断,确定两次采样允许的最大偏差值(设为A) 每次检测到新值时判断: 如果本次值与上次值之差A,则本次值无效,放弃本次值,用上次值代替本次值 B、优点: 能有效克服因偶然因素引起的脉冲干扰 C、缺点 无抑制那周期性的干扰 平滑度差 2、中位值滤波 A、方: 连续采样N次(N取奇数) 把N次采样值按大小排列 取中间值为本次有效值 B、优点: 能有效克服因偶然因素引起的波动干扰 对温度、液位的变化缓慢的被测参数有良好的滤波效果 C、缺点: 对流量、速度等快速变化的参数不宜 3、算术平均滤波 A、方: 连续取N个采样值进行算术平均运算 N值较大时:信号平滑度较高,但灵敏度较低 N值较小时:信号平滑度较低,但灵敏度较高 N值的选取:一般流量,N=12;压力:N=4 B、优点: 适用于对一般具有随机干扰的信号进行滤波 这样信号的特点是有一个平均值,信号在某一数值范围附近上下波动 C、缺点: 对于测量速度较慢或要求数据计算速度较快的实时控制不适用 比较浪费RAM 4、递推平均滤波(又称滑动平均滤波) A、方: 把连续取N个采样值看成一个队列 队列的长度固定为N 每次采样到一个新数据放入队尾,并扔掉原来队首的一次数据.(先进先出原则) 把队列中的N个数据进行算术平均运算,就可获得新的滤波结果 N值的选取:流量,N=12;压力:N=4;液面,N=4~12;温度,N=1~4 B、优点: 对周期性干扰有良好的抑制作用,平滑度高 适用于高频振荡的系统 C、缺点: 灵敏度低 对偶然出现的脉冲性干扰的抑制作用较差 不易消除由于脉冲干扰所引起的采样值偏差 不适用于脉冲干扰比较严重的场合 比较浪费RAM 5、中位值平均滤波(又称防脉冲干扰平均滤波) A、方: 相当于“中位值滤波”+“算术平均滤波” 连续采样N个数据,去掉一个最大值和一个最小值 然后计算N-2个数据的算术平均值 N值的选取:3~14 B、优点: 融合了两滤波的优点 对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差 C、缺点: 测量速度较慢,和算术平均滤波一样 比较浪费RAM 6、限幅平均滤波 A、方: 相当于“限幅滤波”+“递推平均滤波” 每次采样到的新数据先进行限幅处理, 再送入队列进行递推平均滤波处理 B、优点: 融合了两滤波的优点 对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差 C、缺点: 比较浪费RAM 7、一阶滞后滤波 A、方: 取a=0~1 本次滤波结果=(1-a)*本次采样值+a*上次滤波结果 B、优点: 对周期性干扰具有良好的抑制作用 适用于波动频率较高的场合 C、缺点: 相位滞后,灵敏度低 滞后程度取决于a值大小 不能消除滤波频率高于采样频率的1/2的干扰信号 8、加权递推平均滤波 A、方: 是对递推平均滤波的改进,即不同时刻的数据加以不同的权 通常是,越接近现时刻的数据,权取得越大。 给予新采样值的权系数越大,则灵敏度越高,但信号平滑度越低 B、优点: 适用于有较大纯滞后时间常数的对象 和采样周期较短的系统 C、缺点: 对于纯滞后时间常数较小,采样周期较长,变化缓慢的信号 不能迅速反应系统当前所受干扰的严重程度,滤波效果差 9、消抖滤波 A、方: 设置一个滤波计数器 将每次采样值与当前有效值比较: 如果采样值=当前有效值,则计数器清零 如果采样值当前有效值,则计数器+1,并判断计数器是否>=上限N(溢出) 如果计数器溢出,则将本次值替换当前有效值,并清计数器 B、优点: 对于变化缓慢的被测参数有较好的滤波效果, 可避免在临界值附近控制器的反复开/关跳动或显示器上数值抖动 C、缺点: 对于快速变化的参数不宜 如果在计数器溢出的那一次采样到的值恰好是干扰值,则会将干扰值当作有效值导入系统 10、限幅消抖滤波 A、方: 相当于“限幅滤波”+“消抖滤波” 先限幅,后消抖 B、优点: 继承了“限幅”和“消抖”的优点 改进了“消抖滤波”中的某些缺陷,避免将干扰值导入系统 C、缺点: 对于快速变化的参数不宜
按键消抖是指在按下或松开按键时,由于机械性能、电气性能等原因,会产生一些抖动信号。这些抖动信号可能会被误认为是多次按下或松开按键,导致系统出现错误。因此,需要对按键信号进行消抖处理,以确保系统正常运行。 一般的按键消抖算法是基于滤波的,常见的滤波算法有移动平均滤波和中值滤波。其中,移动平均滤波是指对一段时间内的信号取平均值,以减小信号的波动;中值滤波是指对一段时间内的信号取中值,以排除信号中的异常值。 以下是一个基于移动平均滤波的按键消抖的例程: ``` #define KEY_PIN 2 // 定义按键所在引脚 #define KEY_THRESHOLD 3 // 定义按键触发的阈值 #define SAMPLE_NUM 10 // 定义采样次数 #define DELAY_TIME 5 // 定义采样间隔时间 void setup() { pinMode(KEY_PIN, INPUT_PULLUP); // 将按键所在引脚设置为输入模式,并开启上拉电阻 } void loop() { static int samples[SAMPLE_NUM] = {0}; // 定义采样数组 static int sampleIndex = 0; // 定义采样索引 int sum = 0; // 定义采样和 int average = 0; // 定义采样平均值 samples[sampleIndex] = digitalRead(KEY_PIN); // 读取按键状态,并存入采样数组 sampleIndex = (sampleIndex + 1) % SAMPLE_NUM; // 更新采样索引 for (int i = 0; i < SAMPLE_NUM; i++) { sum += samples[i]; // 计算采样和 } average = sum / SAMPLE_NUM; // 计算采样平均值 if (average < KEY_THRESHOLD) { // 判断按键是否被触发 // 执行按键触发后的操作 } delay(DELAY_TIME); // 等待采样间隔时间 } ``` 在上述例程中,首先定义了按键所在引脚、按键触发的阈值、采样次数和采样间隔时间等参数。然后在`setup()`函数中将按键所在引脚设置为输入模式,并开启上拉电阻。在`loop()`函数中,定义了一个静态的采样数组和采样索引,用于存储按键状态的采样值。读取按键状态后,将其存入采样数组中,并更新采样索引。然后计算采样和和采样平均值,判断按键是否被触发,并执行相应的操作。最后延时一定时间,等待下一次采样。这样就实现了对按键信号的消抖处理。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值