回顾一下算术平均滤波法的处理思想:采集N组数据求算术平均值作为单次数据的有效值。
假设N为10,采集某组数据时,若第2次采集时环境已发生较大变化,而我们需要再采集8次数据,才能将数据变化反映到有效值上。可以看出改算法的实时性较差。
而当N取不同值时,大致有一下规律: N↑ 实时性↓ 滤波平滑度↑
为了解决实时性问题,有一种改进算法:递推平均滤波法
其处理思想是:设置一个长度为N的队列,将采集到的数据放到队尾,同时丢弃队首数据;以保证队列中的N个数据都为最新数据。再将队列中的N个数据求算术平均值,作为有效值。
若在某次采集中数据发送较大变化也可实时反映到有效值上。
队列是种特殊的线性表,实现的方法也有很多:例如数组、单链表、循环链表等
本文使用数组实现(设数组长度为N,队首为Quece[N-1],队尾为Quece[0])
其实现原理也很简单:每当有数据进队列时,将所有数组元素右移,丢弃队首数据,再把新数据插入到队尾即可。
#define TARGET_tYPE int #define N 8 //队列 TARGET_tYPE value_buf[N]; //初始化队列 void Init_Queue() { for(int i = 0; i < N; i++) { value_buf[i] = 0; } } //插入队列 void Add_Queue(TARGET_tYPE value) { //数组元素右移 for(int i = N-1; i > 0; i--) { value_buf[i] = value_buf[i-1]; } //插入新元素 value_buf[0] = value; } //求队列和 TARGET_tYPE Sum_Queue() { TARGET_tYPE ADDER = 0; for(int i = 0; i < N; i++) { ADDER = ADDER + value_buf[i]; } return ADDER; } TARGET_tYPE Smoothing_arithmetic_mean_FILTER() { //采集数据插入队列 Add_Queue(get_data()); return Sum_Queue()/N; }
图1. 温度传感器滤波效果
图2. 水位传感器滤波效果
平滑度高,对周期性干扰有良好的抑制作用;实时性较好,非常适用于高频振荡的系统(图2);
灵敏度低,对偶然出现的脉冲干扰抑制性差