Search code examples
caverageadcansi-c

Floating average with reading of ADC values


I want to do moving average or something similar to that, because I am getting noisy values from ADC, this is my first try, just to compute moving average, but values goes to 0 everytime, can you help me?

This is part of code, which makes this magic:

unsigned char buffer[5];
    int samples = 0;
    USART_Init0(MYUBRR);
    uint16_t adc_result0, adc_result1;
    float ADCaverage = 0;

    while(1)
    {

        adc_result0 = adc_read(0);      // read adc value at PA0
        samples++;
        //adc_result1 = adc_read(1);      // read adc value at PA1

        ADCaverage = (ADCaverage + adc_result0)/samples;

        sprintf(buffer, "%d\n", (int)ADCaverage); 
        char * p = buffer;
        while (*p) { USART_Transmit0(*p++); }
        _delay_ms(1000);
    }
    return(0);
}

This result I am sending via usart to display value.


Solution

  • Your equation is not correct.

    Let s_n = (sum_{i=0}^{n} x[i])/n then:

    s_(n-1) = sum_{i=0}^{n-1} x[i])/(n-1)
    
    sum_{i=0}^{n-1} x[i] = (n-1)*s_(n-1)
    sum_{i=0}^{n} x[i] = n*s_n
    
    
    sum_{i=0}^{n} x[i] = sum_{i=0}^{n-1} x[i] + x[n]
    
    n*s_n = (n-1)*s_(n-1) + x[n] =  n*s_(n-1) + (x[n]-s_(n-1))
    s_n = s_(n-1) + (x[n]-s_(n-1))/n
    

    You must use

    ADCaverage += (adc_result0-ADCaverage)/samples;