滤波器开发之一:基于算数平均的平滑滤波器

信号采集是非常常见的需求,我们也总是希望采集到的数据是纯净而真实的,但这只是我们的希望。环境中存在太多的干扰信号,为了让我们得到的数据尽可能地接近实际值,我们需要降低这些干扰信号的影响,于是就有了滤波器的用武之地。这里我们讨论的主要是软件实现的数字滤波器,这一篇我们就来讨论基于递推算术平均算法的平滑滤波器。

1、问题的提出

在我们通过AD采集获取数据时,不可避免会受到干扰信号的影响,而且很多时候我们希望尽可能的将这种影响减到最小。为实现这一目的,人们想了很多办法,有硬件方面的,也有软件方面的。在硬件难以改变或者软件能够达到相应效果时,我们一般采用软件方法来实现,通常称之为数字滤波。

实现数字滤波的算法有很多种,根据不同的应用需求我们可以选择不同滤波算法来实现。对于一般的AD采集最常见的是周期性干扰和随机性噪声,对于此类干扰一般采用算术平均的方法就能得到比较理想的效果。其计算公式如下:

使用简单的算术平均值算法虽然能够实现滤波,但在一些情况下有一个问题可能会有影响,那就是当做算术平均的数量比较大时会出现曲线并不是十分平滑的情况。这很容易理解,因为一次采集n个数做算术平均得到一个结果,当n越大则间隔的时间就越长。为了解决这一问题我们并不是甲酸完后就将n个数同时丢弃,而是将最早的数丢弃并采用最新采集的数代替,这就是所谓的递推算术平均算法。但其计算公式并没有发生变化。

2、算法设计

我们如何实现这种递推方式的平滑滤波器呢?首先我们来看一看一般的算术平均算法是如何实现的。算术平均算法就是采集N个数然后对这N个数取平均值作为最终的结果。我们将这些数的序列记录如下:

这N个数计算完毕后就会丢弃,然后再采集N个数。很显然,如果N值较大,采集所耗费的时间跨度就会比较长,数据看起来可能就并不那么平滑,而且数据的输出速率会慢很多,也不能展示数据的变化过程。而递推平均算法则不存在这些问题。同样是一个长度为N的数据队列,但没采样一次数据,我们就用最新的数据替换掉最久的数据,并输出算术平均值。我们将这些数的序列记录如下:

这样每采样一个数据我们都会输出一个滤波后的数据,而不是等待采集N个数据后才会输出,这样既可保证数据的连续性也可达到平滑滤波的效果。

3、代码实现

我们分析了平滑滤波器的实现算法,接下来我们来讨论如何实现这一滤波器。首先我们将滤波器作为一个对象,我们实现的滤波器操作也将面向这一对象来实现。那么我们实现对滤波器对象的操作需要确定该对象的那些属性呢?

作为滤波器肯定需要获取当前采集到的数据值;同时我们为了实现对N个数据的递推平均就需要有一个存储这N个数的队列;我们需要记录最新的数据硬件存储到哪个位置就需要一个位置指针;同时我们也需要知道N的大小,所以我们将它们都定义滤波器对象的属性。平滑滤波的过程必须要计算算术平均值,而递推算术平均则是在每次采集一个数据之时都计算平均值,可是如果N值较大时,就会存在大量的重复计算。我们考虑到上一次采样的平均值已经得到,我们将其记录下来的话就可以用最新采集的数据替换掉最老的数据,从而得到新的平均值,所以我们将上一时间的输出值记录下来作为对象的一个属性。根据以上分析我们可定义滤波器对象类型为:

/*定义平滑滤波对象类型*/
typedef struct FilterObject{float newValue;       //最新测量值float lastValue;      //上一个输出值float *buffer;        //数据缓存区int16_t position;    //写操作位置指针uint16_t bufCount;    //滤波的数量
}FilterObjectType;

我们获得了滤波器对象,接下来我们基于该对象实现平滑滤波器。对于平滑滤波自然是要采取计算平均值的过程。但我们使用了循环队列的操作方式,所以判断新数据指针当前所处的位置。具体实现如下:

/*平滑滤波处理函数,返回滤波后的值 */
float SmoothingFilter(FilterObjectType *filter)
{float result=0.0;if(filter->position<0){for(int i=0;i<filter->bufCount;i++){filter->buffer[i]=filter->newValue;}filter->position=0;filter->lastValue=filter->newValue;}if(filter->position>=filter->bufCount){filter->position=0;}result=filter->lastValue-filter->buffer[filter->position]/filter->bufCount;result=result+filter->newValue/filter->bufCount;filter->buffer[filter->position++]=filter->newValue;filter->lastValue=result;filter->newValue=0.0;return result;
}

4、应用总结

我们实现了基于算术平均的平滑滤波器,对于消除周期性干扰有良好的抑制作用,对于一般具有随机干扰的信号也能进行滤波。对于数据平滑度较高有不错的效果。

但是这种滤波方式有几点是需要注意的。第一,它的灵敏度低。这很好理解,因为我们总是对N个数采取平均值算法,所以新数据对平均值的影响有限,数据变化不明显,响应较慢,而且N越大越明显。第二.对偶然出现的脉冲性干扰的抑制作用较差。第三,不易消除由于脉冲干扰所引起的采样值偏差。所以这种滤波器并不适用于脉冲干扰比较严重的场合。

欢迎关注:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/499370.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

外设驱动库开发笔记6:AD719x系列ADC驱动

前面我们讨论了AD7705这种ADC器件的驱动开发&#xff0c;在实际中我们使用更多的是AD719x系列的ADC芯片、包括有AD7191、AD7192和AD7193等。接下来我们就来设计并开发AD719x的驱动程序。 1、功能概述 AD7192是一款适合高精密测量应用的低噪声完整模拟前端&#xff0c;内置一个…

滤波器开发之二:基于算数平均的带阻平滑滤波器

信号采集是非常常见的需求&#xff0c;我们也总是希望采集到的数据是纯净而真实的&#xff0c;但这只是我们的希望。环境中存在太多的干扰信号&#xff0c;为了让我们得到的数据尽可能地接近实际值&#xff0c;我们需要降低这些干扰信号的影响&#xff0c;于是就有了滤波器的用…

滤波器开发之三:基于算数平均的阶进平滑滤波器

信号采集是非常常见的需求&#xff0c;我们也总是希望采集到的数据是纯净而真实的&#xff0c;但这只是我们的希望。环境中存在太多的干扰信号&#xff0c;为了让我们得到的数据尽可能地接近实际值&#xff0c;我们需要降低这些干扰信号的影响&#xff0c;于是就有了滤波器的用…

外设驱动库开发笔记7:LTC2400系列ADC驱动

有些时候我们需要对高精度的ADC来处理一些要求较高的模拟量采集。在处理温控器的过程中我们就使用到了LTC2400这款ADC。接下来我们就来设计并实现LTC2400的驱动。 1、功能概述 LTC2400是一个供电电压2.7V到5.5V的微功率24位转换器&#xff0c;集成了振荡器、4ppm INL和0.3ppm…

外设驱动库开发笔记8:GPIO模拟I2C驱动

I2C总线简单方便&#xff0c;是我们经常使用的一种总线。但有时候我们的MCU没有足够多的I2C控制器来实现我们的应用&#xff0c;所幸我可以使用普通的GPIO引脚来模拟低速的I2C总线通信。这一节我们就来实现使用软件通过普通GPIO操作I2C设备的驱动。 1、功能概述 I2C总线使用两…

嵌入式IAP开发笔记之一:面向STM32的BootLoader程序

对于很多人来说&#xff0c;BootLoader并不是一个陌生的词&#xff0c;甚至会经常用到它。因为在很多情况下我们都需要BootLoader程序&#xff0c;比如我们需要对系统在线升级时就需要它&#xff0c;还有当我们需要在外部存储器中运行程序时也需要用到它。在这里我们就来设计一…

外设驱动库开发笔记9:SHT1x系列温湿度传感器驱动

在我们的产品中&#xff0c;经常需要检测温湿度数据。有很多检测温湿度的方法和模块&#xff0c;其中SHT1x系列温湿度传感器就是一种成本较低使用方便的温湿度检测模块。下面我们就来说一说如何实现SHT1x系列温湿度传感器的驱动。 1、功能概述 SHT1x包括 SHT10&#xff0c; S…

Modbus协议栈应用实例之一:Modbus RTU主站应用

自从开源了我们自己开发的Modbus协议栈之后&#xff0c;有很多朋友建议我针对性的做几个示例。所以我们就基于平时我们的应用整理了几个简单但可以说明基本的应用方法的示例&#xff0c;在这一篇中我们先来使用协议栈实现Modbus RTU主站的示例。 1、何为RTU主站 Modbus协议是…

uCOS-III应用开发笔记之一:uCOS-III在STM32的移植

uCOS-III实时操作系统在MCU平台被广泛使用&#xff0c;在这里我们将简单的记录如何将uCOS-III实时操作系统移植到目标平台上并运行。 1、必要的准备 在开始uCOS-III实时操作系统的移植前&#xff0c;我们还需要做一些必要的准备&#xff0c;如确定目标板、准备目标工程及uCOS…

外设驱动库开发笔记10:SHT2x系列温湿度传感器驱动

温湿度检测是嵌入式编程中经常应用到的一项功能。在我们的产品中亦经常使用。SHT2x系列温湿度传感器作为一种高精度低成本的集成模块&#xff0c;一直应用于我们的产品中。在这里我们讨论如何封装SHT2x系列温湿度传感器的驱动。 1、功能概述 SHT20配有一个全新设计的CMOSens芯…

Modbus协议栈应用实例之二:Modbus RTU从站应用

自从开源了我们自己开发的Modbus协议栈之后&#xff0c;有很多朋友建议我针对性的做几个示例。所以我们就基于平时我们的应用整理了几个简单但可以说明基本的应用方法的示例&#xff0c;这一篇中我们将使用协议栈实现一个Modbus RTU从站应用。 1、何为RTU从站 Modbus协议是一…

外设驱动库开发笔记11:SHT3x系列温湿度传感器驱动

在我们的产品中经常会遇到温湿度检测的需求。可以用于检测温湿度的传感器元件也有很多。我们经常使用的SHT各系列数字温湿度传感器来实现应用需求。在这里我们将设计并实现SHT3x系列温湿度传感器的驱动。 1、功能概述 SHT3x系列温湿度传感器是适用于各种应用的高品质湿度传感…

LwIP应用开发笔记之十:LwIP带操作系统基本移植

现在&#xff0c;TCP/IP协议的应用无处不在。随着物联网的火爆&#xff0c;嵌入式领域使用TCP/IP协议进行通讯也越来越广泛。在我们的相关产品中&#xff0c;也都有应用&#xff0c;所以我们结合应用实际对相关应用作相应的总结。 1、技术准备 我们采用的开发平台是STM32F407…

ThreadX应用开发笔记之一:移植ThreadX到STM32平台

现在一些小型系统中也往往有多任务处理的需求&#xff0c;这就为实时操作系统提供了用武之地。事实上国内外各种各样的RTOS有很多&#xff0c;而且基本都在走开源的路线&#xff0c;ThreadX也不例外&#xff0c;在这一篇中我们就来学习ThreadX初步应用并将其移植到STM32平台中。…

外设驱动库开发笔记12:TSEV01CL55红外温度传感器驱动

有时候我们需要检测一些无法直接接触的器件的温度。为了实现这一需求&#xff0c;我们通常会选择红外温度传感器来实现这一功能。考虑到复用的问题&#xff0c;我们一般会将操作元器件的代码抽象为驱动函数以备调用。这里我们就来设计并实现TSEV01CL55红外温度传感器的驱动。 …

FreeRTOS应用开发笔记之一:FreeRTOS在STM32的移植

FreeRTOS是如今在小型嵌入式领域应用比较广泛的一种实时操作系统。它是一种开源且免费的操作系统&#xff0c;而且移植和使用都非常的简单。在这里我们将学习并移植FreeRTOS。 1、必要的准备 工欲善其事&#xff0c;必先利其器&#xff0c;在开始学习和移植之前&#xff0c;相…

外设驱动库开发笔记13:MLX90614红外温度传感器驱动

红外温度传感器一般用于非接触式的温度检测。在我们的系统中经常会有这样的需求。所以我们将其设计为通用的驱动库以备复用。这一篇我们将讲述MLX90614红外温度传感器驱动的设计与实现。 1、功能概述 MLX90614是一种红外温度计&#xff0c;用于非接触式温度测量。红外测温是根…

Modbus协议栈应用实例之三:Modbus TCP客户端应用

自从开源了我们自己开发的Modbus协议栈之后&#xff0c;有很多朋友建议我针对性的做几个示例。所以我们就基于平时我们的应用整理了几个简单但可以说明基本的应用方法的示例&#xff0c;这一篇中我们将解说如何使用协议栈实现一个Modbus TCP客户端。 1、何为TCP客户端 Modbus…

Modbus协议栈应用实例之四:ModbusTCP服务器应用

自从开源了我们自己开发的Modbus协议栈之后&#xff0c;有很多朋友建议我针对性的做几个示例。所以我们就基于平时我们的应用整理了几个简单但可以说明基本的应用方法的示例&#xff0c;这一篇中我们来简述如何使用协议栈实现一个Modbus TCP服务器应用。 1、何为TCP服务器 Mo…

外设驱动库开发笔记14:DS18B20温度变送器驱动

在一时候我们需要相对简单的检测温度信号&#xff0c;而DS18B20就是一款功能和应用都相对简单的温度传感器&#xff0c;通过单线就可以实现检测温度信号的需求。这一篇我们就来实现操作DS18B20获取温度数据的驱动。 1、功能概述 DS18B20是常用的数字温度传感器&#xff0c;其…