2

現在、次の関数を使用して、それぞれ発生している温度測定値の移動平均を計算しています200ms

uint16_t ntc_average(uint16_t adcdata)
{ 

    static uint8_t      first = 1;
    static uint16_t t1,t2,t3,t4,t5;

    if(first == 1)
    {
        first = 0;
        t1 = t2 = t3 = t4 = t5 = adcdata;
    }

    t5 = t4;
    t4 = t3;
    t3 = t2;
    t2 = t1;
    t1 = adcdata;
    adcdata = (t1+t2+t3+t4+t5)/5;

    return(adcdata);
}

ただし、5 ポイントでは十分ではなく、さらに滑らかにするには、はるかに長いバッファーが必要になる場合があります。たとえば、10 ~ 20 の読み取りごとに 1 回または 2 回、値が 1 ポイント上下する可能性があり、それを滑らかにする必要があります。tn 変数を増やすのは見苦しく思えます... t1-t50 が必要かもしれません。

C温度測定値を平滑化するために使用できる別の機能を提案できる人はいますか? 値は符号なし整数であり、float ではないことに注意してください。

4

2 に答える 2

4

算術平均を取らずに平滑化できます。たとえば、移動ウィンドウからドロップする特定のサンプルをダンプするのではなく、反復ごとに平均自体をドロップすることができます。

newAverage = (oldAverage * (windowSize - 1) + newSample) / windowSize;

あなたのシステムには十分かもしれませんし、そうでないかもしれませんが、試してみる価値はあります。

于 2012-12-21T21:09:22.127 に答える
1

これには、単純なフィルターがよく使用されます。

ave = ave * (1-a) + samp * a;

ここaで、 は 0.0 から 1.0 の間の小さな定数です


s0.15 固定小数点:

int32 bigAverage; 
int16 ave;
int16 sample;
int16 alpha = 32768L*(0.1) //your constant here
int16 oneLessAlpha = 32768L-alpha;

//... in loop ...
bigAverage = (bigAverage>>15)*oneLessAlpha;
bigAverage += sample*alpha;
ave = bigAverage>>15;

より良い精度を維持するために、蓄積を長く行います。

于 2012-12-21T21:14:32.743 に答える