I'm getting wild averages that aren't close to the analogRead value of A0.
Here is what I have done so far:
void setup() {
Serial.begin(9600);
}
void loop() {
int average = smoothInput(10, A0);
Serial.println (average);
}
int smoothInput (int numReading, int analogPin) {
int readings[numReading];
int readIndex = 0;
int total = 0;
int average = 0;
total = total - readings[readIndex];
readings[readIndex] = analogRead(analogPin);
total = total + readings[readIndex];
readIndex = readIndex + 1;
if (readIndex >= numReading) {
readIndex = 0;
}
average = total / numReading;
return average;
}
Those variables you declare inside your function smoothInput() lose their value once the function exists. And since you do not create any type of looping within your function, it will only read the analog pin once and then return. Because you do not initialize your readings array, it can contain anything so your function basically does this:
set total to 0
subtract some random value from total
read the analog pin
add that to total
return total/numReadings
you need to have a for() loop inside your function:
int smoothInput (int numReading, int analogPin) {
unsigned int total = 0;
for( int i = 0; i < numReading; ++i ) {
total += analogRead(analogPin);
}
return total / numReading;
}
In the example above, beware of integer overflow, which will happen if "total" exceeds 32767. Keep "numReading(s)" below 32 to ensure this does not happen.
jremington:
In the example above, beware of integer overflow, which will happen if "total" exceeds 32767.
Not true.
Unsigned int is 16 bits so the max is 65535 and since the readings can be 1023, you will not get overflow unless you attempt 65 or more readings to average
blh64:
you need to have a for() loop inside your function:
Or you need to keep the variables outside it, where they will not be discarded when the function exits.
Another thing to be aware of is: how often do you want to sample the input? In your example, all ten samples will be taken within microseconds, but that will change if you add more code that takes a little time to execute. So, you don't get much smoothing and you don't know how much you will get.
// global (aka static) variables are guaranteed to be initialized
// to zero if you don't initialize them.
const int NREADINGS = 10;
int reading[NREADINGS];
int readingTotal = 0; // might go as high as NREADINGS*1024
int readingIndex = 0;
const long readingIntervalMs = 100; // sample every 10th of a second
long mostRecentReadingMs;
void setup() {
// this needs to be initialised, or the intervbal counting
// logic won't work
mostRecentReadingMs = millis();
}
void loop() {
int average = smoothInput(A0);
Serial.println (average);
}
int smoothInput(byte pin) {
if (millis() - mostRecentReadingMs < readingIntervalMs) {
return readingTotal/NREADINGS;
}
// doing it this way keeps the intervals consistent
mostRecentReadingMs += readingIntervalMs;
readingIndex++;
if(readingIndex>=NREADINGS) readingIndex=0;
// forget the old reading
readingTotal -= reading[readingIndex];
// take a new reading
reading[readingIndex] = analogRead(pin);
readingTotal += reading[readingIndex];
return readingTotal/NREADINGS;
}
runningAvg smoother(numDataItems); // Create it by telling it how many data items to keep and average over.
// Use it by passing in data. As you do, it passes back the smoothed version.
// You can also ask for max, min and delta of the contained data.
float smoothData = smoother(newRawDataItem);
This is in your IDE at your fingertips as we text. In the library manager search for LC_baseTools there's bunch of other handy tools in there as well.