CCS does not monitor this forum on a regular basis. Please do not post bug Reports on this forum. Send them to support@ccsinfo.com
Author Message
Ttelmah

Joined: 11 Mar 2010
Posts: 17202

Posted: Wed Apr 22, 2020 2:02 am

There are lots of different ways of filtering the signal from ADC's.
The 'best' depends massively on what the actual error is coming 'from'.
However I've tried to put links here to the types that people have found
useful in the past.

First the simplest. Sum and average:

The most efficient integer divisions on the PIC are the 'binary' divisions.
So /2, /4, /8, /16 etc.. So if you average 4, 8, 16 etc., samples, the
maths is quicker.
This is a simple and effective average, but takes 8 loops before a
reading is returned. An average can also be done using an array of
values, so the result can update with just one new sample. An example
of this is lower down this thread in a post with a median filter as well.

Second, the 'rolling average':
 Code: int16 rolling(void) {     static int32 sum;     int16 val;     static int1 first=TRUE; //used to say this is the first loop     set_adc_channel(1);     delay_us(10);     val=read_adc();     if (first)     {         first=FALSE;         sum=val*8; //load the sum first time     }     else     {         sum=sum+val;     }     val=sum/8;     sum-=val;     return val; }

the exit of the loop, this is divided by 8, and this becomes the result.
The sum then has this result subtracted.
The sum is maintained for each successive call.

Each time the sum maintained is 7* the last result, and then the new
value is added to this and the new average generated.

The effect is that the new result takes 1/8th from the new reading,
but is affected by much older results than the simple average. However
with less and less effect the older the reading. This can be a very
effective way of averaging, and gives you a new result with just one
sample each time it is called.

Then the 'olympic' average. This is a 'simple' average, but throwing
away the highest and lowest values first. Makes it a very good way of
rejecting individual 'outliers'.
Asmboy posted a implementation here:

http://www.ccsinfo.com/forum/viewtopic.php?t=50320&highlight=olympic

Then a more sophisticated filter the 'median' filter. This always returns
a value that is actually 'in' the values being read. It tries to return what
you can think of as the 'central' value. Implementation by PCM_programmer
here:

http://www.ccsinfo.com/forum/viewtopic.php?t=3462&highlight=medianfilter

This also has a basic averaging filter, but using a rolling array of values
allowing a new result with just a single new reading.

In all cases the actual amount of smoothing can be increased or decreased
by changing the number involved, but the more damping, the greater the
'lag' that will be experienced in the output.

Obviously all these filtering techniques can be applied to signals other
than the ADC as well, but the ADC is the one that most people will be
dealing with.
 Display posts from previous: All Posts1 Day7 Days2 Weeks1 Month3 Months6 Months1 Year Oldest FirstNewest First
 All times are GMT - 6 Hours Page 1 of 1

 Jump to: Select a forum Software----------------General CCS C DiscussionCode LibraryEZ App LynxBest Of Hardware----------------CCS ICD / Mach X / Load-n-Go
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum