Moving average code not working

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

Hello All

   

Im currently working on some code to read from TI's LDC1000, one issue with this sensor is the noise, so i require a moving average.  

   

Now ive tried this a few ways and keep seeing the same issue.  an array needs to be written to, read from and over written.  now for some reason the values being written in aren't what get read out.  

   

The array pointer, for some unknown reason counts from 0-99 (100 field array) correctly, then once it fills the first time it then starts going crazy.

   

09,19, 29,39,49,59,69,79,89,99,10,11,12.......99 i cant see how mathematically this is even possible? 

   

then there's the values being called back from the array, given the values written in are +/-50 bits im getting random values over the whole 16bit resolution (65,535). 

   

heres the function for reading the average:

   

uint16 getCurrentRollingAverage(uint16 newValue){
int arrayLength =100;
uint16 measurements[100];
int average = 0;
uint16 poppedValue = 0;
uint32 rollingTotal =0;
if(numAdded < arrayLength){
//rolling total calculation is a simple divide of the
//total until the array is full. No push/pop logic needed.
    rollingTotal = rollingTotal + newValue;
    average = rollingTotal / (numAdded + 1);
    }
else{
    //read the array value that we are about to overwrite, and subtract it from
    //our rolling total so that the average works out correctly.
    poppedValue = measurements[arrayPointer % arrayLength];
    //rolling total now loses the old value we've popped, and gains the new value.
    rollingTotal = rollingTotal + newValue - poppedValue;
    //but we still divide by the arraylength + 1.
    average = rollingTotal / (arrayLength + 1);
    }
//store the new value for later. Store it in the position we've just pulled "poppedValue" from
//and we can now lose this poppedValue as we've used it already.
measurements[arrayPointer] = newValue;

   

//move the global array pointer forwards, or to the end of the array if <0.
arrayPointer = (arrayPointer+1) % arrayLength;
//we want to increment this until the array is full.
if(numAdded <= arrayLength){
    numAdded++;
    }

   


//give the new average.
return average;
}

0 Likes
1 Solution
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

You might declsre your variables as "static" which will keep their contents between calls to your function. Be aware that static vars get initialized only once.

Bob

View solution in original post

3 Replies
HeLi_263931
Level 8
Level 8
100 solutions authored 50 solutions authored 25 solutions authored

One thing I can see: you define measurements as variable in the function. That means its created every time the function called (on the stack), so it probably has new content every time (or not, it might end up in the same place in memory as before). Same for rollingTotal. You need to have them in the same place as numAdded.

Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

You might declsre your variables as "static" which will keep their contents between calls to your function. Be aware that static vars get initialized only once.

Bob

Yes, that's the other option. But I (personally) prefer to keep them outside of the function

0 Likes