信號采集是非常常見的需求,我們也總是希望采集到的數(shù)據(jù)是純凈而真實的,但這只是我們的希望。環(huán)境中存在太多的干擾信號,為了讓我們得到的數(shù)據(jù)盡可能地接近實際值,我們需要降低這些干擾信號的影響,于是就有了濾波器的用武之地。這里我們討論的主要是軟件實現(xiàn)的數(shù)字濾波器,這一篇我們就來討論基于遞推算術(shù)平均算法的平滑濾波器。
1 、問題的提出
在我們通過AD采集獲取數(shù)據(jù)時,不可避免會受到干擾信號的影響,而且很多時候我們希望盡可能的將這種影響減到最小。為實現(xiàn)這一目的,人們想了很多辦法,有硬件方面的,也有軟件方面的。在硬件難以改變或者軟件能夠達到相應(yīng)效果時,我們一般采用軟件方法來實現(xiàn),通常稱之為數(shù)字濾波。
實現(xiàn)數(shù)字濾波的算法有很多種,根據(jù)不同的應(yīng)用需求我們可以選擇不同濾波算法來實現(xiàn)。對于一般的AD采集最常見的是周期性干擾和隨機性噪聲,對于此類干擾一般采用算術(shù)平均的方法就能得到比較理想的效果。其計算公式如下:
使用簡單的算術(shù)平均值算法雖然能夠?qū)崿F(xiàn)濾波,但在一些情況下有一個問題可能會有影響,那就是當(dāng)做算術(shù)平均的數(shù)量比較大時會出現(xiàn)曲線并不是十分平滑的情況。這很容易理解,因為一次采集n個數(shù)做算術(shù)平均得到一個結(jié)果,當(dāng)n越大則間隔的時間就越長。為了解決這一問題我們并不是甲酸完后就將n個數(shù)同時丟棄,而是將最早的數(shù)丟棄并采用最新采集的數(shù)代替,這就是所謂的遞推算術(shù)平均算法。但其計算公式并沒有發(fā)生變化。
2 、算法設(shè)計
我們?nèi)绾螌崿F(xiàn)這種遞推方式的平滑濾波器呢?首先我們來看一看一般的算術(shù)平均算法是如何實現(xiàn)的。算術(shù)平均算法就是采集N個數(shù)然后對這N個數(shù)取平均值作為最終的結(jié)果。我們將這些數(shù)的序列記錄如下:
這N個數(shù)計算完畢后就會丟棄,然后再采集N個數(shù)。很顯然,如果N值較大,采集所耗費的時間跨度就會比較長,數(shù)據(jù)看起來可能就并不那么平滑,而且數(shù)據(jù)的輸出速率會慢很多,也不能展示數(shù)據(jù)的變化過程。而遞推平均算法則不存在這些問題。同樣是一個長度為N的數(shù)據(jù)隊列,但沒采樣一次數(shù)據(jù),我們就用最新的數(shù)據(jù)替換掉最久的數(shù)據(jù),并輸出算術(shù)平均值。我們將這些數(shù)的序列記錄如下:
這樣每采樣一個數(shù)據(jù)我們都會輸出一個濾波后的數(shù)據(jù),而不是等待采集N個數(shù)據(jù)后才會輸出,這樣既可保證數(shù)據(jù)的連續(xù)性也可達到平滑濾波的效果。
3 、代碼實現(xiàn)
我們分析了平滑濾波器的實現(xiàn)算法,接下來我們來討論如何實現(xiàn)這一濾波器。首先我們將濾波器作為一個對象,我們實現(xiàn)的濾波器操作也將面向這一對象來實現(xiàn)。那么我們實現(xiàn)對濾波器對象的操作需要確定該對象的那些屬性呢?
作為濾波器肯定需要獲取當(dāng)前采集到的數(shù)據(jù)值;同時我們?yōu)榱藢崿F(xiàn)對N個數(shù)據(jù)的遞推平均就需要有一個存儲這N個數(shù)的隊列;我們需要記錄最新的數(shù)據(jù)硬件存儲到哪個位置就需要一個位置指針;同時我們也需要知道N的大小,所以我們將它們都定義濾波器對象的屬性。平滑濾波的過程必須要計算算術(shù)平均值,而遞推算術(shù)平均則是在每次采集一個數(shù)據(jù)之時都計算平均值,可是如果N值較大時,就會存在大量的重復(fù)計算。我們考慮到上一次采樣的平均值已經(jīng)得到,我們將其記錄下來的話就可以用最新采集的數(shù)據(jù)替換掉最老的數(shù)據(jù),從而得到新的平均值,所以我們將上一時間的輸出值記錄下來作為對象的一個屬性。根據(jù)以上分析我們可定義濾波器對象類型為:
1 /*定義平滑濾波對象類型*/
2 typedef struct FilterObject{
3 float newValue; //最新測量值
4 float lastValue; //上一個輸出值
5 float *buffer; //數(shù)據(jù)緩存區(qū)
6 int16_t position; //寫操作位置指針
7 uint16_t bufCount; //濾波的數(shù)量
8 }FilterObjectType;
我們獲得了濾波器對象,接下來我們基于該對象實現(xiàn)平滑濾波器。對于平滑濾波自然是要采取計算平均值的過程。但我們使用了循環(huán)隊列的操作方式,所以判斷新數(shù)據(jù)指針當(dāng)前所處的位置。具體實現(xiàn)如下:
1 /*平滑濾波處理函數(shù),返回濾波后的值 */
2 float SmoothingFilter(FilterObjectType *filter)
3 {
4 float result=0.0;
5
6 if(filter->position<0)
7 {
8 for(int i=0;i<filter->bufCount;i++)
9 {
10 filter->buffer[i]=filter->newValue;
11 }
12 filter->position=0;
13 filter->lastValue=filter->newValue;
14 }
15
16 if(filter->position>=filter->bufCount)
17 {
18 filter->position=0;
19 }
20
21 result=filter->lastValue-filter->buffer[filter->position]/filter->bufCount;
22
23 result=result+filter->newValue/filter->bufCount;
24
25 filter->buffer[filter->position++]=filter->newValue;
26
27 filter->lastValue=result;
28
29 filter->newValue=0.0;
30 return result;
31 }
4 、應(yīng)用總結(jié)
我們實現(xiàn)了基于算術(shù)平均的平滑濾波器,對于消除周期性干擾有良好的抑制作用,對于一般具有隨機干擾的信號也能進行濾波。對于數(shù)據(jù)平滑度較高有不錯的效果。
但是這種濾波方式有幾點是需要注意的。第一,它的靈敏度低。這很好理解,因為我們總是對N個數(shù)采取平均值算法,所以新數(shù)據(jù)對平均值的影響有限,數(shù)據(jù)變化不明顯,響應(yīng)較慢,而且N越大越明顯。第二.對偶然出現(xiàn)的脈沖性干擾的抑制作用較差。第三,不易消除由于脈沖干擾所引起的采樣值偏差。所以這種濾波器并不適用于脈沖干擾比較嚴(yán)重的場合。
-
濾波器
+關(guān)注
關(guān)注
161文章
7860瀏覽量
178929 -
數(shù)字濾波器
+關(guān)注
關(guān)注
4文章
270瀏覽量
47093 -
算法設(shè)計
+關(guān)注
關(guān)注
0文章
24瀏覽量
8192
發(fā)布評論請先 登錄
相關(guān)推薦
評論