How would I turn this analog smoothing example into a function?

I'm pretty new to functions (and Programming as a whole.)

I'm trying to turn this example into a function.

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;

}

Thanks for all your help.

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;
}

EDIT: fixed typo

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: Sorry, missed the "unsigned". The code will overflow at 65535.

But do fix the spelling errors in your code, so it will at least compile.

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;
}

I'd use..

runningAvg class.

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.

-jim lee