信號采集是非常常見的需求,我們也總是希望采集到的數(shù)據(jù)是純凈而真實的,但這只是我們的希望。環(huán)境中存在太多的干擾信號,為了讓我們得到的數(shù)據(jù)盡可能地接近實際值,我們需要降低這些干擾信號的影響,于是就有了濾波器的用武之地。這里我們討論的主要是軟件實現(xiàn)的數(shù)字濾波器,這一篇我們就來討論基于遞推算術(shù)平均算法的階進平滑濾波器。
1 、問題的提出
前面一篇我們討論了同時提高靈敏度和濾波效果的方法,在通常情況下,都能達到比較理想的效果。不過在有些情況下,我們的采集對象會是處于一定的區(qū)間內(nèi),并且干擾信號也主要存在于這一區(qū)間內(nèi)。也就是說干擾信號的幅值并不是很大,但持續(xù)存在;而被測信號也基本處于一個穩(wěn)定的被測區(qū)間內(nèi)。在這種情況下,被測信號越是處于目標范圍內(nèi),干擾的影響越是不可忽略。在這一篇中我們就來設(shè)計一種濾波算法實現(xiàn)這樣的需求。
首先,我們來分析一下,干擾信號較小,但持續(xù)不斷對最終數(shù)據(jù)有較大影響。因為在有些應(yīng)用中,當系統(tǒng)穩(wěn)定時,采集的數(shù)據(jù)理論上來講是不應(yīng)該出現(xiàn)很大波動的。基于這一點我們可以考慮對比本次采集與上次輸出之間的偏差值,如果偏差值大于一定的限值則我們認為是數(shù)據(jù)發(fā)生了較大變化,遠大于干擾造成的影響,干擾可以忽略,所以我們直接對數(shù)據(jù)進行更新。當數(shù)據(jù)偏差處于一定的變化范圍之內(nèi)時,但系統(tǒng)并未處于穩(wěn)定狀態(tài),但干擾信號已經(jīng)不能完全忽略了,我們可以進行部分濾波處理。當數(shù)據(jù)偏差小于一定的值之后,我們認為是處于穩(wěn)定的范圍內(nèi),這時干擾造成的影響于數(shù)據(jù)的變化不能忽略,我們需要采用完全濾波。具體如圖所示:
上圖中SL1和SL2是我們要設(shè)定的階進處理區(qū)間限值。當數(shù)據(jù)偏差小于SL2時,干擾信號對最終數(shù)據(jù)的影響較大,我們需要進行完全濾波。當系統(tǒng)變化處于上圖中的SL1和SL2之間時,數(shù)據(jù)差異變較大,干擾信號相比于數(shù)據(jù)本身的變化較小,但不可忽略,我們可以進行不完全濾波來增加系統(tǒng)的靈敏度。當系統(tǒng)處于大于SL1的區(qū)間時,干擾信號對系統(tǒng)的影響很小,我們可以不做濾波處理。
2 、算法設(shè)計
前面描述了這種分段增加濾波作用的濾波器的特點,接下來我們來設(shè)計這種階進式濾波器的操作算法。
首先依然需要一個數(shù)據(jù)隊列,但在不同的情況下,對數(shù)據(jù)隊列的更新形式是不一樣的。在前后兩個數(shù)據(jù)的偏差小于SL2時,這個時候我們需要對這采集數(shù)據(jù)進行完全的濾波處理。這個時候我們只需要用最新的數(shù)據(jù)替換時間最久的老數(shù)據(jù),然后取隊列的算術(shù)平均值就得到輸出數(shù)據(jù)。具體的隊列更新如下:
若是數(shù)據(jù)偏差處于SL1和SL2之間,這個時候干擾信號對采集值的影響變小但并未小到可以忽略,但數(shù)據(jù)的變化幅度已經(jīng)很大,為了提高靈敏度,我們一次更新多個老數(shù)據(jù)以增加新數(shù)據(jù)的在輸出值的比重。具體的隊列更新如下:
若是數(shù)據(jù)偏差大于SL1時,數(shù)據(jù)的變化量已經(jīng)遠超干擾的影響,我們可以忽略干擾信號,為了提高系統(tǒng)靈敏度,我們不需要在進行濾波處理。具體的隊列更新如下:
但是偏差落在大于SL1的范圍內(nèi)時,并不預(yù)示著我們需要馬上更新數(shù)據(jù)隊列的全部數(shù)據(jù),因為可能是偶然性的脈沖干擾,這時我們需要作消抖處理。我們判斷如果連續(xù)多少個的采集數(shù)據(jù)均落在相應(yīng)的區(qū)間,我們就認為不是偶然的脈沖干擾。這是我們就更新隊列的全部數(shù)據(jù)。
3 、代碼實現(xiàn)
我們已經(jīng)詳細描述了階進式平滑濾波器的操作算法,但具體如何實現(xiàn)呢?我們依然將濾波器當作一個對象,我們在此只考慮分成三段的階進式濾波算法,即不濾波,半濾波和全濾波。
我們先來分析一下,首先濾波器對象需要獲取當前采集到的數(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ù),從而得到新的平均值,所以我們將上一時間的輸出值記錄下來作為對象的一個屬性。除此之外,我們還需要知道濾波器的限制區(qū)間,即HL和LL,所以我們將采集數(shù)據(jù)所對應(yīng)的量程范圍、上限(HL)、下限(LL)比例均作為對象的屬性。同時為了實現(xiàn)消抖,我們需要記錄數(shù)據(jù)大幅變化的持續(xù)數(shù)及確認消抖的最大數(shù)值,這兩個也作為對象的屬性。根據(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 uint16_t delayCount; //延遲計數(shù)
9 uint16_t delayLimit; //延遲限值
10 float rangeLimit; //量程范圍
11 float upperRario; //比例下限
12 float lowerRatio; //比例下限
13 }FilterObjectType;
我們已經(jīng)獲得了濾波器對象,接下來將基于這一對象實現(xiàn)相應(yīng)的濾波器功能。我們要對比當前的采集值與上一個輸出值的比較,根據(jù)它們的偏差絕對值來決定采取怎樣的處理方式。處理流程如下:
在偏差值小于SL2時,進行全濾波處理;在偏差值大于SL2而小于SL1時,進行半濾波處理;而在偏差值大于SL1時,不進行濾波處理。根據(jù)以上的分析及流程圖我們可以設(shè)計階進平滑濾波器的代碼為:
1 /* 階梯平滑濾波處理函數(shù),返回濾波后的值*/
2 float StepSmoothingFilter(FilterObjectType *filter)
3 {
4 float result=filter->lastValue;
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 if(fabs(filter->newValue-filter->lastValue)>(filter->rangeLimit*filter->upperRario/100))
22 {
23 filter->delayCount+=1;
24 if(filter->delayCount>=filter->delayLimit)
25 {
26 for(int i=0;i<filter->bufCount;i++)
27 {
28 filter->buffer[i]=filter->newValue;
29 }
30 filter->position++;
31 result=filter->newValue;
32 filter->delayCount=0;
33 }
34 }
35 else if(fabs(filter->newValue-filter->lastValue)>=(filter->rangeLimit*filter->lowerRatio/100))
36 {
37 result=filter->lastValue-filter->buffer[filter->position]/filter->bufCount;
38
39 result=result+filter->newValue/filter->bufCount;
40
41 filter->buffer[filter->position++]=filter->newValue;
42 if(filter->position>=filter->bufCount)
43 {
44 filter->position=0;
45 }
46
47 result=result-filter->buffer[filter->position]/filter->bufCount;
48 result=result+filter->newValue/filter->bufCount;
49 filter->buffer[filter->position++]=filter->newValue;
50
51 filter->delayCount=0;
52 }
53 else
54 {
55 result=filter->lastValue-filter->buffer[filter->position]/filter->bufCount;
56
57 result=result+filter->newValue/filter->bufCount;
58
59 filter->buffer[filter->position++]=filter->newValue;
60
61 filter->delayCount=0;
62 }
63
64 filter->lastValue=result;
65 filter->newValue=0.0;
66 return result;
67 }
4 、應(yīng)用總結(jié)
我們實現(xiàn)了基于算術(shù)平均的階進平滑濾波器。該濾波器對周期性干擾和小幅的噪聲干擾均有較好的效果。而且通過不同偏差值區(qū)間進行不同的濾波處理,在數(shù)據(jù)快速變化時,能很好的提高系統(tǒng)的靈敏度。對于系統(tǒng)處于平穩(wěn)狀態(tài)時,也能收到很好的濾波效果。
這一濾波器有效的前提是基于干擾的幅度并不是很大而且系統(tǒng)的采集值基本能穩(wěn)定在一定范圍內(nèi)的前提而實現(xiàn)的。如果系統(tǒng)存在較大幅度的脈沖干擾,在這種脈沖干擾的出現(xiàn)頻率較低時,消抖操作能夠很好的去除這種偶然性干擾。但如果出現(xiàn)持續(xù)性的高頻大幅脈沖干擾,這一濾波器將變得無能為力。
對于限值區(qū)間SL1和SL2的取值一般只能根據(jù)采集系統(tǒng)的特點或者工程師的經(jīng)驗來判斷,但并非是盲目的,因為很多情況下我們是能夠判斷出干擾信號的大致判斷范圍的。在這些系統(tǒng)中絕大部分的干擾變化會落在SL2的范圍內(nèi),其概率可能會超過60%,而落在SL1范圍內(nèi)的概率可能會超過90%,所以選擇合適的SL1和SL2值會取得良好的濾波效果。
-
濾波器
+關(guān)注
關(guān)注
161文章
7826瀏覽量
178203 -
數(shù)字濾波器
+關(guān)注
關(guān)注
4文章
270瀏覽量
47031 -
算法設(shè)計
+關(guān)注
關(guān)注
0文章
24瀏覽量
8154
發(fā)布評論請先 登錄
相關(guān)推薦
評論