不管你是做数字信号处理还是体系主动控制,只需体系中有模仿数据收集部分,就不可避免的存在噪声搅扰的问题。应对噪声,一个办法便是利用硬件建立模仿的滤波器,在前端采样电路滤除去噪声;另一个办法,便是利用ADC采样,运转软件滤波算法,滤除去信号中的噪声。

特别声明:本文为个人在阅览《匠人笔记》的数字滤波篇后自己总结的输出作用,假如存在侵权,烦请留言奉告处理。

布景常识

软件和硬件滤波两种办法各有优缺点,硬件滤波针对特定信号滤除作用好,能够有用进步体系的信噪比,可是硬件电路杂乱,乃至需求引入运放添加物料成本,一起频带调整不行灵敏,假如噪声信号频率是改变的通常力不从心。软件滤波则设置灵敏,能够便利调整频带,在应对杂乱的噪声信号时,乃至能够引入算法主动跟从噪声频率,可是软件滤波也有缺点,需求耗费很多的CPU能力进行运算,而且体系能够处理的信号带宽直承受ADC采样速率和CPU处理速度的约束,无法像硬件滤波器那样轻易规划出高频段的滤波器。

本文主要介绍软件滤波,因为在原型DEMO的开发中,为了快速滤除噪声,削减规划硬件滤波器的繁琐,咱们直接便是用ADC采样前端信号,然后软件快速滤除噪声开端后续处理,加速咱们的研究进展。

软件滤波介绍

软件滤波是利用CPU强壮的核算运算功能,经过某种数值运算,到达改变输入信号中所含频率分量的相对比例、或滤除某些频率分量的意图。实验中往往会因为噪声、搅扰、温度、环境以及元器件或许设备等许多要素的影响,形成收集到的数据达不到预期作用,例如收集到的“坏点”数据会对数据的剖析以及成果形成晦气的影响。这个时分能够选用软件滤波的办法对收集到的数据进行处理,减小颤动误差,使收集到的数据尽可能的精确。此外除了可运用(有源、无源)滤波器对信号或波形进行滑润处理外,还能够先将波形用A/D收集,然后运用软件滤波,终究经过D/A输出波形,同样能够起到对波形的滑润处理和消除毛刺等作用。
软件滤波的办法有很多种,下面介绍常用的几种,不同的滤波办法运用的场合和环境也不用,应依据具体状况挑选运用。为了直观体现出这几种滤波办法对不同噪声的滤波作用,咱们人为生成了几段根本信号的组合,然后在它们的波形上叠加上不同的噪声,测验这些滤波办法在不同信号、不同噪声下的输出成果,实验数据如下图所示:

通用数字滤波算法

在这段长度为800点,最大值为65535的测验样本中,组合了以下几种状况:

  1. 开端阶段是一段表达式近似为x\sqrt{x}x ​的数据,用来模仿大多数体系从0开端发动的采样波形,该段信号受到了约为信号自身1/5强度的随机噪声的搅扰,用以测验滤波函数对噪声的过滤程度。
  2. 第二段是一段长度为200点的方波信号,其上叠加了起伏为信号自身1/10的毛刺噪声,测验函数对直流采样进程中毛刺的过滤作用以及对阶跃信号的响应速度。
  3. 第三段为一段均匀上升的斜坡信号,可是叠加了几个三角形的噪声信号,用来模仿一些高惯性体系受到脉冲冲击后产生的周期较长的搅扰杂波。
  4. 第四段是一段混有信号自身1/10强度的随机噪声与1/4强度的毛刺噪声,模仿了平常在正弦逆变类标题中常常碰到的体系底噪与周期性开关噪声。
  5. 终究一段是直流信号上叠加了一个长周期的小幅正弦纹波,一起伴有必定的毛刺,用来模仿DC-DC类标题中常呈现的输出伴纹波信号。

上面列出的组合大致涵盖了电子规划比赛中电源类常见的几种状况,因为涉及到PID闭环调理,因而精确的采样与滤波对完成高精度的输出控制与快速反应至关重要。下面咱们就分别介绍这些算法的完成进程与运用作用。

限幅滤波

限幅滤波又称为程序判别滤波,依据屡次收集到的数据,假如当时收集值与前一次收集的数值相差一般维持在必定的误差D\Delta{D}D内,则将每次收集到的数据和前一次的数据进行比较,假如他们的差的绝对值小于D\Delta{D}D则本次收集到的数据有用,否则无效放弃。

示例代码

#include <stdlib.h>
/*********************限幅滤波***********************
/*   sampleValue:当时采样值
/*   return 滤波输出值
/***************************************************/
#define AMPLIMIT 8192
int lastValue = -1;
unsigned int AmpLimitFilter(unsigned int sampleValue)
{
    if(-1 == lastValue)
        lastValue = sampleValue;
	//限幅判别
    if(abs(sampleValue - lastValue) > AMPLIMIT)
    {
        return lastValue;
    }else{
        lastValue = sampleValue;
        return sampleValue;
    }
}

滤波作用

通用数字滤波算法

适用剖析

限幅滤波程序规划简略、运算速度快、占用RAM少,是一种最简略的根本滤波办法。能够战胜偶尔要素引入的脉冲搅扰,也能够消除波形上的尖峰毛刺,可是不能按捺周期性的搅扰,而且其彻底削除大起伏的阶跃信号,简单形成控制失调,一般不适用于开关电源这类改变剧烈,需求敏捷反应的场景,适用于水温控制等改变缓慢,安全性高的运用。

中值滤波

将本来的采样距离T\Delta{T}T进行细分,也便是在本来的采样距离T\Delta{T}T内采样N次,然后把N次采样值依照大小排序,取中间值为本次采样值。

示例代码

/*********************中值滤波***********************
/*   *sampleGet():采样函数指针,回来unsigned int类型
/*   return 滤波输出值
/***************************************************/
#define MID_NUM 5
unsigned int MidFilter(unsigned int *sampleGet())
{
  unsigned char i;
  unsigned int value_buf[MID_NUM]={0};
  for (i=0;i < MID_NUM;i++)
  {
    value_buf[i] = sampleGet();
  }
  unsigned int mid;
  //冒泡排序
  for(i=0;i<MID_NUM;i++)
  {
	int j;
    for(j=i+1;j<MID_NUM;j++)
    {
      if(value_buf[i]>value_buf[j])
      {
        mid=value_buf[i];
        value_buf[i]=value_buf[j];
        value_buf[j]=mid;
      }
    }
  }
  mid=value_buf[MID_NUM/2];
  return mid;
} 

滤波作用

通用数字滤波算法

适用剖析

这种滤波办法能够有用的战胜偶尔要素引起的动摇搅扰,特别是关于像温度、液位等改变缓慢的被测参数有杰出的滤波作用,可是关于流量、速度或许其他快速改变的信号参数则不合适运用这种办法。中值滤波法的程序规划要稍杂乱一些,排序能够运用冒泡法或许挑选排序法等,因为引入了排序算法,所以该办法不能处理速度要求很高的信号。其运算处理速度和占用的RAM直承受所挑选的数值N决议。

算术均匀滤波

该办法也是先将本来规划要求的采样距离T\Delta{T}T进行细分,在T\Delta{T}T内采样N次,可是关于收集进来的数据不是进行排序,而是进行算术均匀,算术均匀的成果作为本次采样值。N值的选取比较要害,N值较大者处理信号的滑润度会较高,可是灵敏度下降;相反,N值较小者处理信号的灵敏度进步,可是滑润度下降。

示例代码

/*********************均值滤波***********************
/*   *sampleGet():采样函数指针,回来unsigned int类型
/*   return 滤波输出值
/***************************************************/
#define AVG_NUM 5
unsigned int AvgFilter(unsigned int *sampleGet())
{
  unsigned char i;
  unsigned long int sum=0;
  for (i=0;i < AVG_NUM;i++)
  {
    sum += (unsigned int)sampleGet();
  }
  return (sum / AVG_NUM);
}

滤波作用

通用数字滤波算法

适用剖析

这种滤波办法是适用于对具有随机搅扰的信号进行处理,而且被处理的信号有必要具有一个均匀值,信号在这个均匀值上下动摇。该办法关于高速信号并不适用。关于毛刺信号,能够看到均值滤波将其分管到了周围的采样点上,不如中值滤波那样能够彻底去除。可是关于随机噪声信号,因为其理论均值为0,均值滤波对榜首段噪声有杰出的滤除作用。该滤波办法运算处理速度和RAM的占用率也受所挑选的数值N决议,能够运用时间杂乱度较低的排序办法下降运算开支。

递推均匀滤波

递推均匀滤波又称为滑动均匀滤波,是将接连N个采样值设为一个先入先出的行列,行列的长度为N,每次采样得到的新数据加入队尾,并扔掉原行列的队首,然后对行列中的N个数据进行算术均匀,取得的成果作为此次采样值。

示例代码

/*******************递推均值滤波*********************
/*   sampleQueue[SLIDE_AVG_NUM]:采样行列
/*   sampleValue:当时采样值
/*   return 滤波输出值
/***************************************************/
#define SLIDE_AVG_NUM 5
unsigned int sampleQueue[SLIDE_AVG_NUM] = {0};
unsigned int SlideAvgFilter(unsigned int sampleValue)
{
    unsigned int i;
    unsigned long int sum=0;
    for(i = 0; i < SLIDE_AVG_NUM - 1; i ++) //改写行列
    {
        sampleQueue[i] = sampleQueue[i + 1];
    }
    sampleQueue[i] = sampleValue;
    for (i=0;i < SLIDE_AVG_NUM;i++) //求和
    {
        sum += sampleQueue[i];
    }
    return (sum / SLIDE_AVG_NUM);//取均匀
}

滤波作用

通用数字滤波算法

适用剖析

上图为滤波长度为5的输出波形,下图为滤波长度为20的输出波形。能够看到长度为20的波形更好但推迟也更大。可见该办法关于周期性搅扰有杰出的按捺作用,滑润度也很高。可是灵敏度较低,关于偶尔呈现的脉冲搅扰的按捺作用较差,不适用于脉冲搅扰比较严峻的场合,其运算处理速度和RAM的占用率也直承受N值影响。

另外,这种办法还有一个特殊用法:制作成软件陷波器,滤除某个单一频率信号的搅扰(如工频搅扰)。具体完成办法介绍如下:因为正弦波一个周期内任取N个等分点的幅值和为零,其它周期波形的N等分点的幅值和为常数C,设每次采样值为Xi{X_i}Xi​,采样的均匀值为Y=1N∑i=0N−1Xi{Y=\frac{1}{N}\sum_{i=0}^{N-1}}{X_i}Y=N1​∑i=0N−1​Xi​。若取N=SfN=\frac{S}{f}N=fS​(其间S为每秒的采样次数即采样率;f是要消除的波形的频率,S和N都取整数),这样终究的成果便是Y-C,关于50Hz的工频搅扰,C为零,只需挑选合适的N和S就能够直接将其消除,构成一个陷波器。
关于本测验样例,咱们针对终究一段的纹波规划滤波器,因为这里是测验的一组数组,没有采样率概念,可是依据前面的关系换算,设置滤波点数为100点,对终究一段纹波进行了较好的滤除,因为这一段数据较少,加之前面数据的相移影响,读者可自己结构一段足够长的纹波信号验证,作用将更加显着。

通用数字滤波算法

中值均匀滤波

中值均匀滤波也称为防脉冲搅扰均匀滤波,相当于中值滤波和算术均匀滤波思想的结合。接连采样N个数据,去掉其间的最大值和最小值,求剩余的N-2个数据的算术均匀作为一次采样值。

示例代码

/*******************中值均匀滤波*********************
/*   *sampleGet():采样函数指针,回来unsigned int类型
/*   return 滤波输出值
/***************************************************/
#define MID_AVG_NUM 5
unsigned int MidAvgFilter(unsigned int *sampleGet())
{
  unsigned char i;
  unsigned int value_buf[MID_AVG_NUM]={0};
  unsigned int max,min;
  unsigned long int sum=0;
  for (i=0;i < MID_AVG_NUM;i++)
  {
    value_buf[i] = sampleGet();
  }
  max=0;
  min=0xffffffff;
  for(i=0;i<MID_AVG_NUM;i++)
  {
    sum += value_buf[i];//求和
    if(value_buf[i]>max)
    {
      max=value_buf[i];	//找出最大值
    }
    if(value_buf[i]<min)
    {
      min=value_buf[i];	//找出最小值
    }
  }
  return (sum-min-max)/(MID_AVG_NUM-2);//去掉最大最小值,取均匀
}

滤波作用

通用数字滤波算法

适用剖析

此法归纳了两种滤波法的长处,能够有用按捺、消除脉冲搅扰,一起相关于纯中值滤波更加滑润,但因为核算开支加上均值的推迟作用,它也只能用在速度比较慢的场合,不合适高速环境,运算处理速度和RAM占有率由N决议。

递推中值均匀滤波

递推中值均匀滤波也称为滑动中值均匀滤波,与上一种不同的是选用滑动办法对序列采样,不下降体系采样率与采样速度。设定一个长度为N的先进先出行列,一起为了便利排序一起结构一个同样长度为N的已排序数组,每个周期采样一个新的数值,插入采样行列队尾并移除队首的旧值。对这个行列进行插入排序(其他快速排序办法均可),然后去掉用户指定个数的较大值与较小值,取中间剩余值的均匀数作为终究成果。

示例代码

/*******************中值均匀滤波*********************
/*   SLIDE_MID_AVG:数据存储结构体,每路信号对应一个
/*   *sma:本路信号对应结构体指针
/*   newValue:本次采样值
/*   cutNum:排序行列头尾要放弃的数量
/*   return 滤波输出值
/***************************************************/
#define SLIDE_MID_AVG_NUM 32
typedef struct SLIDE_MID_AVG{
	volatile unsigned int sample_queue[SLIDE_MID_AVG_NUM];
	volatile unsigned int sort_queue[SLIDE_MID_AVG_NUM];
} SLIDE_MID_AVG;
SLIDE_MID_AVG sma;
unsigned int SlideMidAvgFilter(SLIDE_MID_AVG *sma,unsigned int newValue,unsigned int cutNum)
{
	unsigned int i;
	unsigned int sum = 0;
	unsigned int insert_value = newValue;
	//在排序序列中移除采样序列中最早的值
	for(i = 0;i < SLIDE_MID_AVG_NUM;i ++)
	{
		if(sma->sort_queue[i] == sma->sample_queue[0])
		{
			unsigned int j;
			for(j = i;j< SLIDE_MID_AVG_NUM - 1;j ++)
			{
				//排序序列向前缩进
				sma->sort_queue[j] = sma->sort_queue[j + 1];
			}
			break;
		}
	}
	//在排序序列中插入新的采样值(插入排序加速运算)
	for(i = 0;i < SLIDE_MID_AVG_NUM - 1;i ++)
	{
		if(insert_value < sma->sort_queue[i])
		{
			unsigned int j;
			for(j = SLIDE_MID_AVG_NUM - 1;j > i;j --)
			{
				//排序序列向后缩进
				sma->sort_queue[j] = sma->sort_queue[j - 1]; 
			}
			sma->sort_queue[i] = insert_value;
			break;
		}else{
			if(i == SLIDE_MID_AVG_NUM - 2)
			{
				sma->sort_queue[SLIDE_MID_AVG_NUM - 1] = insert_value;
			}
		}
	}
	//记载新的值到采样行列结尾
	for(i = 0;i < SLIDE_MID_AVG_NUM - 1;i ++)
	{
		sma->sample_queue[i] = sma->sample_queue[i + 1];		//移位改写
	}
	sma->sample_queue[SLIDE_MID_AVG_NUM - 1] = insert_value;	//采样新值
	//核算中间数的均匀值
	for(i = cutNum; i < (SLIDE_MID_AVG_NUM - cutNum);i ++)
	{
		sum += sma->sort_queue[i];
	}
	return sum / (SLIDE_MID_AVG_NUM - (cutNum << 1));
}

滤波作用

通用数字滤波算法

适用剖析

上图选用了32点滤波长度,首尾去除8个点,波形滑润,没有突变的噪声与毛刺现象,对各种噪声适应性比较均衡,是咱们电子比赛实践中运用的最多的一种滤波办法。可是仔细的读者能够发现,波形向后的推迟很高,差不多与滤波长度相当,这也是此办法的坏处。所以咱们常常运用32点或许64点乃至更长的滑动中值均匀滤波进行数据校准阶段的信号滤波,在恒压恒流等到达精确的稳态值后换用前面的中值滤波等高灵敏度办法进行PID的整定与调理,取得体系高速的动态响应。

限幅均匀滤波

顾名思义,限幅均匀滤波便是将限幅滤波和递推均匀滤波的思想结合起来,每次采样得到的数据先进行限幅处理,再送入行列进行递推均匀滤波处理。
该法也是结合两种滤波法的长处,有用按捺偶尔呈现的脉冲搅扰、可消除由此而引起的采样误差,但不适用于高速信号的处理,其运算处理和RAM的占用率直承受N值影响。

一阶滞后滤波

取一个比例常数k(其间0<k<1),本次输出的成果=k本次采样值+(1-k)前一次输出值,当时的输出值不仅受当时采样值的影响还受前次的输出值影响,影响的程度由k值决议。
该滤波办法适用于动摇频率较高的场合,关于周期性搅扰具有杰出的按捺作用且运算量不大。可是该办法会形成相位滞后,滞后程度取决于k值,灵敏度低,而且不能消除频率高于采样频率一半的搅扰信号。

加权递推均匀滤波

该办法是递推均匀滤波的一种改进,在不一起刻采样进来的数据具有不同的权重。通常状况是距离当时时间越近的采样值的权重越大(特殊状况在外)。赋予刚刚采样得到的数据的权重越大,则灵敏度越高,可是信号的滑润度下降。
此法适用于有较大纯滞后时间常数的目标和采样周期短的状况。关于改变缓慢、采样周期长的状况,则不能敏捷反映体系当时所受搅扰的严峻程度。该办法占用RAM较多。

消抖滤波

设置一个滤波计数器,将每次采样值与当时的有用值比较,假如采样值等于当时有用值,计数器清零;反之,计数器加一,并确判别滤波计数器是否到达设定的溢出上限。假如计数器溢出,将本次的值替换当时有用值,并清零计数器。
此法对改变缓慢的被测参数有较好的滤波作用,并可避免体系在临界值附近时显示器上数值的颤动和控制器的重复开关跳动。但此法不适用于快速改变的参数测量控制。

限幅消抖滤波

限幅消抖滤波为限幅滤波和消抖滤波的结合:先进行限幅处理,再进行消抖滤波处理。

此办法归纳了限幅滤波和消抖滤波的长处,改进了消抖滤波中的一些不足,避免了将搅扰值导入体系,但不适用于快速改变的参数。

根本的软件滤波办法如上所述,(数字滤波器也属于软件滤波,也有其运用的场合,可是耗费的资源会更大些,)这些软件滤波的办法适用场合不同,要依据不同的环境和被测参数的特征来挑选不同的滤波办法,也能够几种办法混合运用,以到达按捺、消除搅扰,滑润波形,消除颤动,安稳控制和输出成果的意图。

用法小结

上面关于几种常见的滤波办法进行了详细的剖析验证,后面几种滤波办法实践上是前面根本滤波的组合,在此不做赘述,读者能够依照前面的进程自行编写代码验证。本书验证在32位渠道下运转,在实践的单片机渠道运转时,读者若参照上面示例代码运转,请注意渠道的数据字长,避免数据溢出的现象发生。

从上述剖析进程咱们能够大致得出:中值滤波适用于去除信号中的突发毛刺,均值滤波适用于去除信号中的白噪声以及体系底噪等。普通的滤波若运用多个采样点核算出一个终究成果,会经过牺牲采样率来取得较精确的数据成果。递推的数据滤波不会下降数据采样的速率,跟着行列长度的添加,输出会越来越滑润。可是信号对阶跃信号的响应会越来越慢,体系的时延会越来越大。所以实践运用中运用者应依据实践信号的类型及噪声的状态选取合适的滤波办法,合适的滤波参数。关于电子规划比赛的电源部分,主张是在数据校准的进程中运用高精确度的滤波来对电压电流等进行精确校准,然后在PID调理时再换用响应快、灵敏度高的滤波算法,这样往往能够一起取得电源输出高精确度、高反应调理速度的作用。