CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

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

Averaging or filtering?

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
neurus



Joined: 31 Mar 2004
Posts: 23
Location: Switzerland

View user's profile Send private message

Averaging or filtering?
PostPosted: Sun Feb 20, 2005 2:08 pm     Reply with quote

hi
In my project I have to make an art integration time. I've an ADC, wich gib me every 0,5 second a value. The integration time goes from 0 to 60 seconds. How can I do to sample the values and calculate the average value of this? It should be as exactly as posible. My ADC is 16 Bits and I'm working with a 18F252 and CCS. Can help me to resolv this problem? has everyone a example to show me how it works?
Thanks and sorry for my english.
Pablo

So works it:

int. time value
0 second every 0,5 second 1 adc value
1 second 2 adc values each 0,5 sec.
10 seconds 20 adc values
etc

I've see a lot of example of filters and averaging routines, but it mus be as exactly as possible.

I forgot something:the process is slowly, the programroutine mus not be to fast but I don't work with float number, if is possible.
Ttelmah
Guest







PostPosted: Mon Feb 21, 2005 6:02 am     Reply with quote

The filters you have seen posted, are almost certainly 'exact'. However there are different kinds of filters for different applications. The best 'compromise', which behaves rather like a leaky integrator, is:
Code:

int16 average(int16 adval) {
    static int32 avgsum;
    int16 result;
    avgsum+=adval;
    result=avgsum/120;
    avgsum-=result;
    return(result);
}

This has the advantage of not needing much storage, giving a nice result, and being relatively quick to calculate. The actual 'damping' level, is set by the divider used, and in terms of fastest speed, and minimum code, using a binary value (2,4, 8 etc.), reduces the time needed for the arithmetic.
The alternative is a simple sum and divide. The downside of this, is that if the result wants to be a 'rolling' value, updated every half second, you need storage for (in your case), 120 int16 values. This is relatively easy on a 18F chip, but may be a problem on the smaller chips. So something like:
Code:

int16 average(int16 adval) {
    static int16 vals[120];
    static int8 index;
    static int32 avgsum;
    int16 result;
    avgsum+=adval;
    avgsum-=vals[index];
    vals[index]=adval;
    result=avgsum/120;
    index=(index+1)%120;
    return(result);
}

This avoids having to add all 120 values each time, by maintaining the sum, and just adding the new value, and subtracting the old.
If you call this with the ADC value, every half second, the returned value, is the sum of the last 120 readings, divided by 120.

Best Wishes
guest
Guest







Question for Ttelmah
PostPosted: Fri Jun 10, 2005 5:19 pm     Reply with quote

Is there a simple way to throw a flag whenever all 120 values are within +/- 5 of eachother?

Thanks
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2005 phpBB Group