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