1.限幅滤波法(程序判断滤波法)

方法:确定两次采样允许的最大偏差值,如果本次值与上次值之差<=A,则本次有效,反之>A,则本次值无效,放弃本次值,上次代替本次值。

优点:克服偶然误差造成的干扰

缺点:无法抑制周期性干扰,平滑度差

核心内容:

1
2
3
4
5
6
7
8
9
10
#define A 10
char value;
char filter()
{
char new_value;
new_value = get_ad();
if ( ( new_value - value > A ) || ( value - new_value > A )
return value;
else return new_value;
}

eg:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include "stdio.h"
#define A 4
float data_number[] = {1.2 , 1.3, 3.1, 2.1, 32, 2.4, 2.3, 4.1};
float input(void);
float filter(void);
static int n = 0;
int main(void)
{
int i = 0;
float sum[7];

for(i = 0; i < 7; i++)
{
sum[i] = filter();
printf("%f\r\n", sum[i]);
}

return 0;

}
float input(void)
{
static int j = 0;
float data1;

j++;
data1 = data_number[j];

return data1;
}
float filter(void)
{
static float new_value;
static float value;

if(n == 0)
{
value = data_number[0];
n = 1;
}else{
value = new_value;
}

new_value = input();
printf("n=%f v=%f\r\n",new_value, value);
if((new_value-value > A))
{
return value;
}else{
return new_value;
}
}

2.中位值滤波法

方法:连续采样 N 次( N 取奇数)把 N 次采样值按大小排列取中间值为本次有效值。
优点:能有效克服因偶然因素引起的波动干扰,对温度、液位的变化缓慢的被测参数有良好的滤波效果。
缺点:对流量、速度等快速变化的参数不宜 。

一般处理椒盐噪声(脉冲噪声),噪声来自于ADC采样,传感器等。

核心:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#define N 11
char filter()
{
char value_buf[N];
char count,i,j,temp;
for ( count = 0;count < N; count++)
{
value_buf[count] = get_ad();
delay();
}
for (j=0;j<N-1;j++) //冒泡法
{
for (i=0;i<N-1-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;
}
}
}
return value_buf[(N-1)/2];
}

eg:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <stdio.h>
#define N 5
int num[N] = {1,5,2,12,6};
int filter();
int input();
int main(void)
{
int med;
med = filter();
printf("med = %d", med);
return 0;
}
int input(void)
{
static int j = 0 ;
int data;

data = num[j];
j++;

return data;
}
int filter(void)
{
int value_buf[N];
int count, i, j, temp;
temp = 0;
for(count = 0; count < N; count++)
{
value_buf[count] = input();
}
for(j = 0; j < N-1 ; j++)
{
for(i = 0; i < N-1-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;
}
}
}

return value_buf[(N-1)/2];
}

把滤波区间的数据从小到大进行排序,然后取中值,(如果是奇数个数据,那么中值就只有一个了,如果偶数个数据,中值有两个,可以对两个数据再求平均,

是把要处理的数据用中值代替,不是全部放成中值。

3.算术平均滤波

方法:连续取 N 个采样值进行算术平均运算,N 值较大时:信号平滑度较高,但灵敏度较低N 值较小时:信号平滑度较低,但灵敏度较高,N 值的选取:一般流量, N=12;压力: N=4。
优点:
适用于对一般具有随机干扰的信号进行滤波,这样信号的特点是有一个平均值,信号在某一数值范围附近上下波动。
缺点:
对于测量速度较慢或要求数据计算速度较快的实时控制不适用,比较浪费 RAM 。

一般处理高斯噪声,噪声来源于热产生,是随机噪声,服从高斯分布。

核心:

1
2
3
4
5
6
7
8
9
10
11
#define N 12
char filter()
{
int sum = 0;
for ( count=0;count<N;count++)
{
sum + = get_ad();
delay();
}
return (char)(sum/N);
}

但是缺点明显,但是u低于偶然异常,对于某次的采样明显偏大,经过平均计算后导致最终值存在较大偏差,针对这种极大值或者极小值,可以在算数平均前进行剔除。

改进的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int filter(void)
{
int i;
int sum = 0;
int min = 0, max = 0;
for(i = 0; i < SAMPLE_NUM; i++)
{
if(vBat[i] < max)
{
max = vBat[i];
}
if(vBat[i] < min)
{
min = vBat[i];
}
sum += vBat[i];
}
sum = sum - min - max;

return sum/SAMPL_NAM;
}

4、递推平均滤波法(又称滑动平均滤波法)

方法:
把连续取 N 个采样值看成一个队列,队列的长度固定为 N,每次采样到一个新数据放入队尾,并扔掉原来队首的一次数据.(先进先出原则)
把队列中的 N 个数据进行算术平均运算,就可获得新的滤波结果,N 值的选取:流量, N=12;压力: N=4;液面, N=412;温度, N=14
优点:
对周期性干扰有良好的抑制作用,平滑度高,适用于高频振荡的系统
缺点:
灵敏度低,对偶然出现的脉冲性干扰的抑制作用较差,不易消除由于脉冲干扰所引起的采样值偏差,不适用于脉冲干扰比较严重的场合,
比较浪费 RAM

核心:

1
2
3
4
5
6
7
8
9
10
11
12
#define N 12
char value_buf[N];
char i=0;
char filter()
{
char count;
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);
}