美文网首页Arduino玩转ArduinoArduino 专题学习
五大滤波算法原理、场景及实践

五大滤波算法原理、场景及实践

作者: Bing的天涯路 | 来源:发表于2020-01-03 19:11 被阅读0次

    在传感器采集数据的过程中,难免因为各种各样的干扰产生异常值,滤波分为电路滤波和算法滤波。电路滤波是从源头上解决(缓解)问题,但是使用成本比较高,即使使用了电路滤波也是不能保证每次采集的数据都是准确的,因为在实际的工作状态中遇到的干扰各种各样,算法滤波的成本比较低,基本思想是采集多次数据对这些采集的数据进行处理最后选择(或计算)出一个可靠的数据放入数据库,要注意算法滤波需要建立在电路滤波的基础上,因此将两者结合起来才能够保证每次写入数据库的数据是可靠的。

    • 限幅滤波法
    • 中位值滤波法
    • 算术平均滤波法
    • 一阶滞后滤波法
    • 限幅消抖滤波法

    限幅滤波法(又称程序判断滤波法)

    A、思路: 根据经验判断,确定两次采样允许的最大偏差值(设为A),每次检测到新值时判断:如果本次值与上次值之差<=A,则本次值有效,如果本次值与上次值之差>A,则本次值无效,放弃本次值,用上次值代替本次值。
    B、优点: 能有效克服因偶然因素引起的脉冲干扰。
    C、缺点: 无法抑制那种周期性的干扰。 平滑度差。

    int Filter_Value;
    int Value;
     
    void setup() {
      Serial.begin(9600);       // 初始化串口通信
      randomSeed(analogRead(0)); // 产生随机种子
      Value = 300;
    }
     
    void loop() {
      Filter_Value = Filter();       // 获得滤波器输出值
      Value = Filter_Value;          // 最近一次有效采样的值,该变量为全局变量
      Serial.println(Filter_Value); // 串口输出
      delay(50);
    }
     
    // 用于随机产生一个300左右的当前值
    int Get_AD() {
      return random(295, 305);
    }
     
    // 限幅滤波法(又称程序判断滤波法)
    #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;
    }
    

    中位值滤波法

    A、方法:

    连续采样N次(N取奇数),把N次采样值按大小排列,

    取中间值为本次有效值。

    B、优点:

    能有效克服因偶然因素引起的波动干扰;

    对温度、液位的变化缓慢的被测参数有良好的滤波效果。

    C、缺点:

    对流量、速度等快速变化的参数不宜。

    int Filter_Value;
     
    void setup() {
      Serial.begin(9600);       // 初始化串口通信
      randomSeed(analogRead(0)); // 产生随机种子
    }
     
    void loop() {
      Filter_Value = Filter();       // 获得滤波器输出值
      Serial.println(Filter_Value); // 串口输出
      delay(50);
    }
     
    // 用于随机产生一个300左右的当前值
    int Get_AD() {
      return random(295, 305);
    }
     
    // 中位值滤波法
    #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];
    }
    

    算术平均滤波法

    A、方法:

    连续取N个采样值进行算术平均运算:

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

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

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

    B、优点:

    适用于对一般具有随机干扰的信号进行滤波;

    这种信号的特点是有一个平均值,信号在某一数值范围附近上下波动。

    C、缺点:

    对于测量速度较慢或要求数据计算速度较快的实时控制不适用;

    比较浪费RAM。

    int Filter_Value;
     
    void setup() {
      Serial.begin(9600);       // 初始化串口通信
      randomSeed(analogRead(0)); // 产生随机种子
    }
     
    void loop() {
      Filter_Value = Filter();       // 获得滤波器输出值
      Serial.println(Filter_Value); // 串口输出
      delay(50);
    }
     
    // 用于随机产生一个300左右的当前值
    int Get_AD() {
      return random(295, 305);
    }
     
    // 算术平均滤波法
    #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);
    }
    

    一阶滞后滤波法

    A、方法:

    取a=0-1,本次滤波结果=(1-a)本次采样值+a上次滤波结果。

    B、优点:

    对周期性干扰具有良好的抑制作用;

    适用于波动频率较高的场合。

    C、缺点:

    相位滞后,灵敏度低;

    滞后程度取决于a值大小;

    不能消除滤波频率高于采样频率1/2的干扰信号。

    int Filter_Value;
    int Value;
     
    void setup() {
      Serial.begin(9600);       // 初始化串口通信
      randomSeed(analogRead(0)); // 产生随机种子
      Value = 300;
    }
     
    void loop() {
      Filter_Value = Filter();       // 获得滤波器输出值
      Serial.println(Filter_Value); // 串口输出
      delay(50);
    }
     
    // 用于随机产生一个300左右的当前值
    int Get_AD() {
      return random(295, 305);
    }
     
    // 一阶滞后滤波法
    #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;
    }
    

    限幅消抖滤波法

    A、方法:

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

    先限幅,后消抖。

    B、优点:

    继承了“限幅”和“消抖”的优点;

    改进了“消抖滤波法”中的某些缺陷,避免将干扰值导入系统。

    C、缺点:

    对于快速变化的参数不宜。

    int Filter_Value;
    int Value;
     
    void setup() {
      Serial.begin(9600);       // 初始化串口通信
      randomSeed(analogRead(0)); // 产生随机种子
      Value = 300;
    }
     
    void loop() {
      Filter_Value = Filter();       // 获得滤波器输出值
      Serial.println(Filter_Value); // 串口输出
      delay(50);
    }
     
    // 用于随机产生一个300左右的当前值
    int Get_AD() {
      return random(295, 305);
    }
     
    // 限幅消抖滤波法
    #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;
    }
    

    本文作者熊冰,个人网站Bing的天涯路,转载请注明出处。

    相关文章

      网友评论

        本文标题:五大滤波算法原理、场景及实践

        本文链接:https://www.haomeiwen.com/subject/cyltactx.html