前言
在嵌入式開(kāi)發(fā)程序中涉及數(shù)據(jù)采樣如傳感器采樣,AD采樣等如果直接讀取信號(hào)后,將信號(hào)值直接參與后續(xù)邏輯處理,若程序無(wú)軟件濾波,會(huì)導(dǎo)致靜態(tài)或者動(dòng)態(tài)采樣時(shí):
1、信號(hào)曲線相對(duì)沒(méi)有那么平滑。
2、同時(shí)可能存在脈沖干擾導(dǎo)致邏輯判斷錯(cuò)誤。
在信號(hào)處理系統(tǒng)中,輸入信號(hào)通常含有各種噪聲和干擾。 為對(duì)信號(hào)進(jìn)行準(zhǔn)確的測(cè)量和控制,必須削弱或?yàn)V除被測(cè)信號(hào)中的噪聲和干擾。 因此在工程應(yīng)用需要使用軟件濾波,軟件濾波也稱數(shù)字濾波,是通過(guò)一定的算法削弱噪聲的影響。 在實(shí)際的開(kāi)發(fā)過(guò)程中使用了滑動(dòng)窗口濾波算法來(lái)對(duì)傳感器的數(shù)據(jù)采樣進(jìn)行濾波處理。
一、圖解滑動(dòng)窗口濾波器的原理
1、建立采樣窗口和濾波窗口,自定義各窗口長(zhǎng)度大小。
2、當(dāng)數(shù)據(jù)樣本點(diǎn)數(shù)未填滿采樣窗口,對(duì)采樣窗口內(nèi)的數(shù)據(jù)累加做平均值計(jì)算。
例如此時(shí)采樣窗口內(nèi)數(shù)據(jù)采樣點(diǎn)只有4個(gè),小于定義的采樣窗口長(zhǎng)度,則將4個(gè)值累加后再做平均值計(jì)算。
3、當(dāng)數(shù)據(jù)樣本點(diǎn)數(shù)已填滿采樣窗口,進(jìn)行冒泡排序后,去除n個(gè)最大值及最小值后,對(duì)濾波窗口內(nèi)的數(shù)據(jù)累加做平均值運(yùn)算。
例如此時(shí)采樣窗口內(nèi)數(shù)據(jù)采樣點(diǎn)有7個(gè),已填滿定義長(zhǎng)度大小的采樣窗口,則分別去除自定義的1個(gè)最大值和1個(gè)最小值后,對(duì)剩余濾波窗口內(nèi)的數(shù)據(jù)累加后再做平均值計(jì)算。
4、新的數(shù)據(jù)樣本到來(lái),移除采樣窗口中時(shí)間最早的點(diǎn)(FIFO),重復(fù)上述3操作。
二、滑動(dòng)窗口濾波器的特點(diǎn)
1、經(jīng)過(guò)濾波處理后,濾除了噪聲干擾,數(shù)據(jù)波動(dòng)穩(wěn)定平滑。
2、每采樣一個(gè)新數(shù)據(jù),就將最早采集的那個(gè)數(shù)據(jù)丟掉,因此每進(jìn)行一次采樣,就可計(jì)算出一個(gè)新的平均值,從而加快了數(shù)據(jù)處理的速度。
3、可以根據(jù)實(shí)時(shí)性的要求和需要濾波后數(shù)據(jù)的平滑度來(lái)設(shè)置采樣窗口和濾波窗口的大小。
4、當(dāng)采樣的數(shù)據(jù)量非常大時(shí),這時(shí)的采樣窗口會(huì)設(shè)置很大,那么窗口需要消耗一定的內(nèi)存空間。
5、當(dāng)采樣數(shù)據(jù)越多,數(shù)據(jù)實(shí)時(shí)性越差,當(dāng)數(shù)據(jù)突然發(fā)生較大變化時(shí),不能被立刻檢測(cè)到,無(wú)法及時(shí)處理突發(fā)事件。
三、滑動(dòng)窗口濾波器的C++代碼實(shí)現(xiàn)
1、基本思路
1、在工程根目錄下新建filter文件夾,將源文件filter.cpp和頭filter.h放在文件夾中供修改調(diào)用。
2、頭文件:
(1)定義濾波算法函數(shù)中的可修改宏值;
(2)聲明定義的濾波函數(shù)模板;
(3)使用extern的方式聲明實(shí)例化后的模板函數(shù)。
3、源文件:
(1)定義需要使用濾波算法的函數(shù)模板;
(2)在定義的函數(shù)模板后進(jìn)行函數(shù)實(shí)例化操作,通過(guò)這樣的方法實(shí)現(xiàn)具體的模板函數(shù)。
2、頭文件filter.h
#ifndef _FILTER_H_
#define _FILTER_H_
#define MAX_SENSOR_NUM 9 //使用濾波時(shí)的傳感器數(shù)量
#define MAX_DATA_NUM 9 //最大采樣點(diǎn)數(shù)量,即采樣窗口長(zhǎng)度
#define WINDOW_DATA_NUM 5 //濾波窗口長(zhǎng)度
//去除采樣窗口內(nèi)最大最小值的數(shù)量,這里去除兩個(gè)最大和兩個(gè)最小
#define REMOVE_MAXMIN_NUM ((MAX_DATA_NUM - WINDOW_DATA_NUM)/2)
//extern double m_dataList[MAX_SENSOR_NUM][MAX_DATA_NUM];
//聲明定義的函數(shù)模板
template<typename InType> InType Filter_SlidingWindowAvg(int index, InType data);
//使用extern的方式聲明實(shí)例化后的模板函數(shù),根據(jù)實(shí)際需要自定義數(shù)據(jù)類型
extern template short Filter_SlidingWindowAvg(int index, short data);
extern template unsigned int Filter_SlidingWindowAvg(int index, unsigned int data);
#endif
3、源文件filter.cpp
#include
#include "Filter.h"
using namespace std;
//定義各個(gè)傳感器的數(shù)據(jù)采樣點(diǎn)列表
double m_dataList[MAX_SENSOR_NUM][MAX_DATA_NUM] = {0};
//滑窗均值濾波,使用函數(shù)模板可用于適配不同數(shù)據(jù)類型的采樣點(diǎn)
template<typename InType>
InType Filter_SlidingWindowAvg(int index, InType data)
{
static int dataNum[MAX_SENSOR_NUM] = {0}; //定義記錄傳感器的采樣點(diǎn)個(gè)數(shù)
int i;
double sum = 0;
double out = 0;
double array[MAX_DATA_NUM] = {0};
//數(shù)據(jù)采樣點(diǎn)在采樣窗口內(nèi)移動(dòng),F(xiàn)IFO操作
for(i = MAX_DATA_NUM - 2; i >= 0; i--)
m_dataList[index][i+1] = m_dataList[index][i];
m_dataList[index][0] = data;
//數(shù)據(jù)采樣點(diǎn)數(shù)量小于采樣窗口長(zhǎng)度,對(duì)采樣窗口數(shù)據(jù)累加后進(jìn)行平均值運(yùn)算
if(dataNum[index] < MAX_DATA_NUM)
{
dataNum[index]++;
for(i = 0; i < dataNum[index]; i++)
{
sum += m_dataList[index][i];
}
out = sum / dataNum[index];
}
//數(shù)據(jù)采樣點(diǎn)已填滿采樣窗口,進(jìn)行排序后,去除n個(gè)最大值及最小值后,對(duì)濾波窗口內(nèi)的數(shù)據(jù)累加后進(jìn)
//行平均值運(yùn)算
else
{
for(i = 0; i < MAX_DATA_NUM; i++)
{
array[i] = m_dataList[index][i];
}
//利用C++標(biāo)準(zhǔn)庫(kù)的sort函數(shù)進(jìn)行排序,這里使用默認(rèn)的升序
sort(array, array + MAX_DATA_NUM);
int start = (MAX_DATA_NUM - WINDOW_DATA_NUM) / 2; //start = REMOVE_MAXMIN_NUM
for(i = start; i < start + WINDOW_DATA_NUM; i++)
{
sum += array[i];
}
out = sum / WINDOW_DATA_NUM;
}
return out;
}
//對(duì)函數(shù)模板進(jìn)行函數(shù)實(shí)例化操作,根據(jù)實(shí)際需要自定義數(shù)據(jù)類型
template short Filter_SlidingWindowAvg(int index, short data);
template unsigned int Filter_SlidingWindowAvg(int index, unsigned int data);
四、滑動(dòng)窗口濾波器的C代碼實(shí)現(xiàn)
1、基本思路
1、在工程根目錄下新建filter文件夾,將頭filter.h和源文件filter.c放在文件夾中供修改調(diào)用。
2、頭文件:
(1)定義濾波算法函數(shù)中的可修改宏值;
(2)聲明定義的濾波算法函數(shù);
3、源文件:
(1)定義冒泡排序功能函數(shù);
(2)定義濾波算法功能函數(shù)。
2、頭文件filter.h
#ifndef _FILTER_H_
#define _FILTER_H_
#define MAX_SENSOR_NUM 9 //使用濾波時(shí)的傳感器數(shù)量
#define MAX_DATA_NUM 9 //最大采樣點(diǎn)數(shù)量,即采樣窗口長(zhǎng)度
#define WINDOW_DATA_NUM 5 //濾波窗口長(zhǎng)度
//去除采樣窗口內(nèi)最大最小值的數(shù)量,這里去除兩個(gè)最大和兩個(gè)最小
#define REMOVE_MAXMIN_NUM ((MAX_DATA_NUM - WINDOW_DATA_NUM)/2)
//extern double m_dataList[MAX_SENSOR_NUM][MAX_DATA_NUM];
//聲明定義的函數(shù)
double Filter_SlidingWindowAvg(int index, double data);
#endif
3、源文件filter.c
#include "Filter.h"
//定義各個(gè)傳感器的數(shù)據(jù)采樣點(diǎn)列表
double m_dataList[MAX_SENSOR_NUM][MAX_DATA_NUM] = {0};
//冒泡排序
void BubbleSort(int array[], int len)
{
int temp;
//外層循環(huán)控制排序的趟數(shù),n個(gè)元素排序需要循環(huán)n-1次
for(int i=0; i
-
傳感器
+關(guān)注
關(guān)注
2565文章
52971瀏覽量
767197 -
嵌入式
+關(guān)注
關(guān)注
5150文章
19659瀏覽量
317390 -
濾波器
+關(guān)注
關(guān)注
162文章
8135瀏覽量
182003 -
C++
+關(guān)注
關(guān)注
22文章
2119瀏覽量
75268 -
AD采樣
+關(guān)注
關(guān)注
0文章
23瀏覽量
16441
發(fā)布評(píng)論請(qǐng)先 登錄
梳狀濾波器以及積分梳狀濾波器的FPGA實(shí)現(xiàn)

數(shù)字濾波器的設(shè)計(jì)和實(shí)現(xiàn)

3*3窗口生成模塊,用于生成濾波的滑動(dòng)窗口,得到窗口內(nèi)的所有元素?cái)?shù)據(jù)
LabVIEW如何實(shí)現(xiàn)數(shù)字濾波器的設(shè)計(jì)
有源濾波器中數(shù)字低通濾波器的設(shè)計(jì)及其DSP實(shí)現(xiàn)
滑動(dòng)濾波器型譜分析器在極窄帶濾波中的應(yīng)用

詳細(xì)解析濾波器的定義,濾波器的特性,濾波器的工作原理,濾波器的分類,濾波器的典型電路原理圖

通過(guò)滑動(dòng)平均濾波器解決數(shù)控系統(tǒng)加減速控制的跳變問(wèn)題

采用FPGA實(shí)現(xiàn)多級(jí)CIC濾波器的四倍抽取一

高斯濾波器的原理和實(shí)現(xiàn)

空間濾波器matlab實(shí)現(xiàn)

高通濾波器和低通濾波器的關(guān)系
腔體濾波器和介質(zhì)濾波器的區(qū)別
滑動(dòng)窗口算法技巧

評(píng)論