cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F1xx - How to implement moving average - SOLVED

Gabriel Germanovix
Associate II
Posted on February 23, 2014 at 16:42

The original post was too long to process during our migration. Please click on the attachment to read the original post.
5 REPLIES 5
francescatodiego
Associate II
Posted on February 23, 2014 at 18:47

What does not work?

http://en.wikipedia.org/wiki/Moving_average

We describe some possible formulas

I used the moving average window

You need to store N consecutive samples where N is the width of the window

The average value is

Mn +1 = Mn - sample (n - N) / N + sample (n +1) / N

or in the best form

N * Mn +1 = N*Mn - sample (n - N) + sample (n +1)

and divide by N only when necessary. (

But you must be careful N*Mn must be stored in 32bit ma

x)

In other words, remove from the average the buffer oldest value and add the last measure

Sample data buffer can be implemented with a circular buffer.

( last measure replaces the oldest value and you can easily calculate the above formula )

At powerup

fill ALL the data buffer with 

the first A/D measure (This prevent the startup delay caused by average )

If possible, for evrey measure exec multiple high speed A/D conversions and

performs the average of these measures

Normally  I exec 10 high speed A/D conversion I subtract the min and the max values ​​and I shift right 3 time (8 divide) the results

This value is my new sample.

ks..
Gabriel Germanovix
Associate II
Posted on February 24, 2014 at 01:42

Thanks for explanations... and wiki link.. but not solved the problem

Gabriel Germanovix
Associate II
Posted on February 27, 2014 at 02:17

Hello Diego,

In terms of functions, interrupts and config things.. Did you have any example to show?

In my codes i divide the buffer on two parts:

The newest and the oldest part...

When the interruptions (HT or TC) are called the other half of buffer is subtracted and current part is added. (see the interruption of DMA)

I stored a certain amount of data and then do the calculations .. 

The initial values ​​are correct but after some time the values ​​begin to show errors. If the input voltage varies widely the error is even greater. 

Even though I keep constant signal after a large variation results are never consistent. Only resetting the module restore the correct values of average.

Tkz...

francescatodiego
Associate II
Posted on February 27, 2014 at 09:05

germanovix

for me it is impossible to find a problem just by reading some of the code without debugging support

I would do this:

Control the number and sequence of the DMA interrupt eg using counters that increments on flags HT and CT ( If you lose a few interrupts as you see it )

Control of the data buffer .

I would use only two input values ​​(eg two batteries 1.2V and 2.4V ) each time you fill a buffer check that all the values are correct .

Start acquisitions test at very low frequency to verify interrupt dma etc.

If you have free ram created a temporary buffer where download all

acquired

data, or if possible send buffer to serial port

I do not know if there is an error in the calculations but to do a test: create a know data buffer (ex a ramp) calculate the moving average for te know buffer and save all the results in another buffer

Remove the DMA transfer and work with conversion complete interrupt

Another test

add increment counter in DMA interrupt and

decrement counter when data is processed

When you start buffer processing the counter value must be 1 (not > 1)

frankmeyer9
Associate II
Posted on February 28, 2014 at 10:17

The initial values ​​are correct but after some time the values ​​begin to show errors. If the input voltage varies widely the error is even greater. 

 

 

Even though I keep constant signal after a large variation results are never consistent. Only resetting the module restore the correct values of average.

Sounds to me like an overflow in your calculation.

However, I suggest to separate your issues. Pull your moving-average implementation/functions out and test them on a PC. I'm using the CodeBlocks IDE for such purposes. This lets you feed the algorithm with simulated input data, watch the intermediate results in the debugger, and verify it.

Only then I would go on to check if the input data feed (ADC/DMA) is correct.