在传感器采集数据的过程中,难免因为各种各样的干扰产生异常值,滤波分为电路滤波和算法滤波。
电路滤波是从源头上解决(缓解)问题,但是使用成本比较高,即使使用了电路滤波也是不能保证每次采集的数据都是准确的,因为在实际的工作状态中遇到的干扰各种各样,算法滤波的成本比较低,基本思想是采集多次数据对这些采集的数据进行处理最后选择(或计算)出一个可靠的数据放入数据库,要注意算法滤波需要建立在电路滤波的基础上,因此将两者结合起来才能够保证每次写入数据库的数据是可靠的。
限幅滤波法中位值滤波法算术平均滤波法一阶滞后滤波法限幅消抖滤波法限幅滤波法(又称程序判断滤波法)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 1int 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 101int 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 12int 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.01int 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 5int 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://bingxiong.vip/)),转载请注明出处。