creating an average in arduino

i need help with finding the average input of a sensor on my arduino how would i write it up in code otis
otis

Posts: 19
Joined: Sat Jul 11, 2009 5:03 pm

Re: creating an average in arduino

The basic process i would use is to define an array for a series of readings, then you make all the readings:

Code: Select all | TOGGLE FULL SIZE
`int readings[5]int i;for(i=0; i<5; i++){readings[i] = analogRead(sensorPin);}int avgReading = (readings[0] + readings[1] + readings[2] + readings[3] + readings[4])/5; `

That should give you an idea of what you need to do. Obviously you need to make that work with your current code. One thing you also probably want to change is the delay between the readings to give you a more meaningful average. Hope that helps!
s133p

Posts: 9
Joined: Wed Jul 15, 2009 1:37 am

Re: creating an average in arduino

Another way is keep adding succesive reads to a total. Increment a counter every time you add a read. At some point divide the total by the counter.

zener

Posts: 3295
Joined: Sat Feb 21, 2009 2:38 am

Re: creating an average in arduino

if your number of samples happens to be power of two you can use a shift instead of a divide and save a hell of a lot of time. i.e.

Code: Select all | TOGGLE FULL SIZE
`  reading = 0;  for (i=0; i<4; i++) {    reading += analogRead(sensorPin);  }  reading >>= 2;`
"i want to lead a dissipate existence, play scratchy records and enjoy my decline" - iggy pop, i need more

mtbf0

Posts: 1645
Joined: Sat Nov 10, 2007 12:59 am
Location: oakland ca

Re: creating an average in arduino

mtbf0 wrote:if your number of samples happens to be power of two you can use a shift instead of a divide and save a hell of a lot of time. i.e.

I wondered about that. I assume you are talking processor cycles? How much faster is it? How much smaller does it make your code?

zener

Posts: 3295
Joined: Sat Feb 21, 2009 2:38 am

Re: creating an average in arduino

The division time doesn't matter. The Arduino analogRead() takes about 100 microseconds. The Arduino library uses an ADC prescaler of 128 and it takes 13 ADC clocks for a normal conversion so that is 1664 cpu clocks.

You might save a few bytes of flash for the divide but not enough to really matter.

Edit:
I tried several cases and the shift is generally bigger

This takes 1828 bytes:
Code: Select all | TOGGLE FULL SIZE
`void setup(){  Serial.begin(9600);    uint8_t n = 4;  uint16_t v = 0;  for (uint8_t i = 0 ; i < n; i++) {    v += analogRead(0);  }  v = v >> 2;  Serial.println(v);}void loop(){}`

This takes 1794 bytes (note n = 5):

Code: Select all | TOGGLE FULL SIZE
`void setup(){  Serial.begin(9600);    uint8_t n = 5;  uint16_t v = 0;  for (uint8_t i = 0 ; i < n; i++) {    v += analogRead(0);  }  v = v/n;  Serial.println(v);}void loop(){}`

But this take 1828 bytes (note n = 4):
Code: Select all | TOGGLE FULL SIZE
`void setup(){  Serial.begin(9600);    uint8_t n = 4;  uint16_t v = 0;  for (uint8_t i = 0 ; i < n; i++) {    v += analogRead(0);  }  v = v/n;  Serial.println(v);}void loop(){}`

Who knows what the compiler will do!
fat16lib

Posts: 593
Joined: Wed Dec 24, 2008 1:54 pm

Re: creating an average in arduino

A simple way to do a moving average is to use floating point math.
Code: Select all | TOGGLE FULL SIZE
`float adcResult = 0;void setup(){  Serial.begin(9600);}void loop(){  adcResult = adcResult * 0.95 + analogRead(0) * 0.05;  Serial.println(adcResult);  delay(50);}`

It's computationally a little heavier but gives pretty good results. The filter above is similar to a 20-point moving average, meaning that changes will appear instantly on the output, but will be moderated by previous values. It's good when you want smoothed values with minimal lag; you don't have to wait to collect 20 samples, you just throw away a small piece of the old value and add in a small piece of the new value.

You could do this with integers too, 7*adcResult + analogRead(0) and then divide by 8 or shift right by 3. You just have to make sure not multiply by too much or you'll have to switch to longs.

A true moving average, based on a rolling buffer, does have some advantages too. You can decide how to weight older values, or try to throw away outlying data points from sporadic noise. But it does use up more memory.
macetech LLC - http://www.macetech.com

macegr

Posts: 290
Joined: Fri Apr 04, 2008 4:46 pm