Site icon AranaCorp

Implementation of the moving average in Arduino

4.5
(17)

An analogue sensor sends a voltage level, usually between 0 and 5V, representing a physical value. This voltage can be subject to measurement noise (electronic interference, electromagnetic interference, measurement accuracy, etc.). In some applications, you will need a fairly stable value to make your calculations or to detect the events you are interested in. A simple method to set up is the sliding average method which allows you to modify the value read according to the measurement history.

Hardware

Principle of operation

The principle of rolling average is to record a certain number of measurements in an array and then average these values at each reading. There are several shortcomings to this:

Schematic

An analogue input is preferably connected to an analogue pin on the microcontroller. There is no additional connection required to operate the sliding average. It is a purely algorithmic solution. For more controlled results, it is possible to put electronic filters on your measurement circuit.

Code

We are going to create a function that will read the analog input and manage the table and the calculation of the average. In this code we have placed a delay() in the loop, so that the display on the serial monitor is slower. Be sure to remove this delay() for more consistent results.

//Parameters
const int aisPin  = A0;
const int numReadings  = 10;
int readings [numReadings];
int readIndex  = 0;
long total  = 0;

//Variables
int aisVal  = 0;

void setup() {
  //Init Serial USB
  Serial.begin(9600);
  Serial.println(F("Initialize System"));
  //Init AnalogSmooth
  pinMode(aisPin, INPUT);
}

void loop() {
  readAnalogSmooth();
  Serial.print(F("ais avg : ")); Serial.println(smooth());
  delay(200);
}

void readAnalogSmooth( ) { /* function readAnalogSmooth */
  ////Test routine for AnalogSmooth
  aisVal = analogRead(aisPin);
  Serial.print(F("ais val ")); Serial.println(aisVal);
}

long smooth() { /* function smooth */
  ////Perform average on sensor readings
  long average;
  // subtract the last reading:
  total = total - readings[readIndex];
  // read the sensor:
  readings[readIndex] = analogRead(aisPin);
  // add value to total:
  total = total + readings[readIndex];
  // handle index
  readIndex = readIndex + 1;
  if (readIndex >= numReadings) {
    readIndex = 0;
  }
  // calculate the average:
  average = total / numReadings;

  return average;
}




Result

On the serial monitor we see that the raw value fluctuates between 306 and 308 while the moving average remains stable at 305.

Applications

Sources

Find other examples and tutorials in our Automatic code generator
Code Architect

How useful was this post?

Click on a star to rate it!

Average rating 4.5 / 5. Vote count: 17

No votes so far! Be the first to rate this post.

Exit mobile version