may you explain this algorithm of calculate to average for noise

Viewed 83

I am working on embedded programming with written code by other people.

this algorithm be used in calculate average for mic and accelerometer

      sound_value_Avg = 0;
      sound_value = 0;
      memset((char *)soundRaw, 0x00, SOUND_COUNT*2);
    
      for(int i2=0; i2 < SOUND_COUNT; i2++)
      {
        soundRaw[i2] = analogRead(PIN_ANALOG_IN);
        if (i2 == 0)
        {
          sound_value_Avg = soundRaw[i2];
        }
        else
        {
          sound_value_Avg = (sound_value_Avg + soundRaw[i2]) / 2;
        }
      }
    
      sound_value = sound_value_Avg;

acceleromter is similar to this

n1=p1

(n2+p1)/2 = p2

(n3+p2)/2 = p3

(n4+p3)/2 = p4

...

avg(n1~nx)=px

it not seems to be correct.

can someone explain why he used this algorithm?

is it specific way for sin graph? like noise, vibration?

1 Answers

It appears to be a flawed attempt at maintaining a cumulative mean. The error is in believing that:

An+1 = (An + sn) / 2

when in fact it should be:

An+1 = ((An * n) + s) / (n + 1)

However it is computationally simpler to maintain a running sum and generate an average in the usual manner:

S = S + s An = S / n

It is possible that the intent was to avoid overflow when the sum grows large, but the attempt is mathematically flawed.

To see how wrong this statement is consider:

        True 
n   s   Running Avg.    (An + sn) / 2
--------------------------------------
1   20  20              20
2   21  20.5            20.25
3   22  21              20.625

In this case however, nothing is done with the intermediate mean value, so you don'e in fact need to maintain a running mean at all. You simply need to accumulate a running sum and calculate the average at the end. For example:

      sum = 0 ;
      sound_value = 0 ;
      
      for( int i2 = 0; i2 < SOUND_COUNT; i2++ )
      {
        soundRaw[i2] = analogRead( PIN_ANALOG_IN ) ;
        sum += soundRaw[i2] ;
      }
    
      sound_value = sum / SOUND_COUNT ;

In this you do need to make sure that the data type forsum can accommodate a value of the maximum analogRead() return multiplied by SOUND_COUNT.

However you say that this is used for some sort of signal conditioning or processing of both a microphone and an accelerator. These devices have rather dissimilar bandwidth and dynamics, and it seems rather unlikely that the same filter would suit both. Applying robust DSP techniques such as IIR or FIR filters with suitably calculated coefficients would make a great deal more sense. You'd also need a suitable fixed sample rate that I am willing to bet is not achieved by simply reading the ADC in a loop with no specific timing

Related