Skip to content

Commit

Permalink
Add method to calculate shorter-term average using only a specified
Browse files Browse the repository at this point in the history
number of the most recent data points.
Closes #14. Closes #11.
  • Loading branch information
JChristensen committed Feb 24, 2022
1 parent bde0db6 commit 393cc83
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 7 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,20 @@ The moving average value. *(int)*
int sensorMovingAvg = mySensor.getAvg();
```

### getAvg(int nPoints)
##### Description
Like `getAvg()` except only uses the most recent `nPoints` data points to calculate the average. This allows calculation of shorter term and longer term averages. If `nPoints` is less than one, or larger than the number of points given in the constructor, then the overall average is returned, i.e. the same value as `getAvg()` would return.
##### Syntax
`getAvg(nPoints);`
##### Parameters
**nPoints:** The number of points to use to calculate a shorter-term average. *(int)*
##### Returns
The moving average value. *(int)*
##### Example
```c++
int sensorMovingAvg = mySensor.getAvg(4);
```

### getCount()
##### Description
Returns the number of data points collected for the moving average, a number between zero and *interval*. This function can be used to determine if a valid moving average exists. This may be useful, for example, to avoid calling `getAvg()` before any data points have been added to the moving average. Calling `getAvg()` before any data points are added causes a divide by zero which will result in invalid data and/or undefined/undesired behavior.
Expand Down
42 changes: 42 additions & 0 deletions examples/Subset/Subset.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Arduino Moving Average Library
// https://github.com/JChristensen/movingAvg
// Copyright (C) 2020 by Jack Christensen and licensed under
// GNU GPL v3.0, https://www.gnu.org/licenses/gpl.html
//
// Example sketch to demonstrate calculating shorter term averages
// from a subset of the data, using just the most recent data points.

#include <movingAvg.h> // https://github.com/JChristensen/movingAvg

constexpr int arraySize {30};
movingAvg foo(arraySize);

void setup()
{
Serial.begin(115200);
foo.begin();

// generate some sample data
for (int i=1; i<=arraySize; ++i) {
foo.reading(i);
}

Serial.print("Average overall: ");
Serial.println(foo.getAvg());
Serial.print("Average last 10: ");
Serial.println(foo.getAvg(10));
Serial.print("Average last 3: ");
Serial.println(foo.getAvg(3));
Serial.print("Average last 2: ");
Serial.println(foo.getAvg(2));
Serial.print("Average last 1: ");
Serial.println(foo.getAvg(1));
Serial.print("Average last 0: ");
Serial.println(foo.getAvg(0));
Serial.print("Average last 30: ");
Serial.println(foo.getAvg(30));
Serial.print("Average last 31: ");
Serial.println(foo.getAvg(31));
}

void loop() {}
4 changes: 2 additions & 2 deletions library.properties
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
name=movingAvg
version=2.2.0
version=2.3.0
author=Jack Christensen <[email protected]>
maintainer=Jack Christensen <[email protected]>
sentence=A simple Arduino library for calculating moving averages.
paragraph=Useful for smoothing sensor readings, etc. For efficiency, the library operates in the integer domain; therefore the moving average calculation is approximate.
category=Data Processing
url=https://github.com/JChristensen/movingAvg
architectures=avr
architectures=*
24 changes: 19 additions & 5 deletions src/movingAvg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,12 @@ void movingAvg::begin()
int movingAvg::reading(int newReading)
{
// add each new data point to the sum until the m_readings array is filled
if (m_nbrReadings < m_interval)
{
if (m_nbrReadings < m_interval) {
++m_nbrReadings;
m_sum = m_sum + newReading;
m_sum += newReading;
}
// once the array is filled, subtract the oldest data point and add the new one
else
{
else {
m_sum = m_sum - m_readings[m_next] + newReading;
}

Expand All @@ -37,6 +35,22 @@ int movingAvg::getAvg()
return (m_sum + m_nbrReadings / 2) / m_nbrReadings;
}

// return the average for a subset of the data, the most recent nPoints readings.
// for invalid values of nPoints, just return the overall average.
int movingAvg::getAvg(int nPoints)
{
if (nPoints < 1 || nPoints > m_interval - 1) {
return (m_sum + m_nbrReadings / 2) / m_nbrReadings;
}
else {
long sum {0};
for (int i=m_nbrReadings-1; i>=m_nbrReadings-nPoints; --i) {
sum += m_readings[i];
}
return (sum + nPoints / 2) / nPoints;
}
}

// start the moving average over again
void movingAvg::reset()
{
Expand Down
1 change: 1 addition & 0 deletions src/movingAvg.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class movingAvg
void begin();
int reading(int newReading);
int getAvg();
int getAvg(int nPoints);
int getCount() {return m_nbrReadings;}
void reset();
int* getReadings() {return m_readings;}
Expand Down

0 comments on commit 393cc83

Please sign in to comment.