Skip to content

Commit 393cc83

Browse files
committed
Add method to calculate shorter-term average using only a specified
number of the most recent data points. Closes #14. Closes #11.
1 parent bde0db6 commit 393cc83

5 files changed

Lines changed: 78 additions & 7 deletions

File tree

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,20 @@ The moving average value. *(int)*
7979
int sensorMovingAvg = mySensor.getAvg();
8080
```
8181

82+
### getAvg(int nPoints)
83+
##### Description
84+
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.
85+
##### Syntax
86+
`getAvg(nPoints);`
87+
##### Parameters
88+
**nPoints:** The number of points to use to calculate a shorter-term average. *(int)*
89+
##### Returns
90+
The moving average value. *(int)*
91+
##### Example
92+
```c++
93+
int sensorMovingAvg = mySensor.getAvg(4);
94+
```
95+
8296
### getCount()
8397
##### Description
8498
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.

examples/Subset/Subset.ino

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Arduino Moving Average Library
2+
// https://github.com/JChristensen/movingAvg
3+
// Copyright (C) 2020 by Jack Christensen and licensed under
4+
// GNU GPL v3.0, https://www.gnu.org/licenses/gpl.html
5+
//
6+
// Example sketch to demonstrate calculating shorter term averages
7+
// from a subset of the data, using just the most recent data points.
8+
9+
#include <movingAvg.h> // https://github.com/JChristensen/movingAvg
10+
11+
constexpr int arraySize {30};
12+
movingAvg foo(arraySize);
13+
14+
void setup()
15+
{
16+
Serial.begin(115200);
17+
foo.begin();
18+
19+
// generate some sample data
20+
for (int i=1; i<=arraySize; ++i) {
21+
foo.reading(i);
22+
}
23+
24+
Serial.print("Average overall: ");
25+
Serial.println(foo.getAvg());
26+
Serial.print("Average last 10: ");
27+
Serial.println(foo.getAvg(10));
28+
Serial.print("Average last 3: ");
29+
Serial.println(foo.getAvg(3));
30+
Serial.print("Average last 2: ");
31+
Serial.println(foo.getAvg(2));
32+
Serial.print("Average last 1: ");
33+
Serial.println(foo.getAvg(1));
34+
Serial.print("Average last 0: ");
35+
Serial.println(foo.getAvg(0));
36+
Serial.print("Average last 30: ");
37+
Serial.println(foo.getAvg(30));
38+
Serial.print("Average last 31: ");
39+
Serial.println(foo.getAvg(31));
40+
}
41+
42+
void loop() {}

library.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
name=movingAvg
2-
version=2.2.0
2+
version=2.3.0
33
author=Jack Christensen <jack.christensen@outlook.com>
44
maintainer=Jack Christensen <jack.christensen@outlook.com>
55
sentence=A simple Arduino library for calculating moving averages.
66
paragraph=Useful for smoothing sensor readings, etc. For efficiency, the library operates in the integer domain; therefore the moving average calculation is approximate.
77
category=Data Processing
88
url=https://github.com/JChristensen/movingAvg
9-
architectures=avr
9+
architectures=*

src/movingAvg.cpp

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,12 @@ void movingAvg::begin()
1515
int movingAvg::reading(int newReading)
1616
{
1717
// add each new data point to the sum until the m_readings array is filled
18-
if (m_nbrReadings < m_interval)
19-
{
18+
if (m_nbrReadings < m_interval) {
2019
++m_nbrReadings;
21-
m_sum = m_sum + newReading;
20+
m_sum += newReading;
2221
}
2322
// once the array is filled, subtract the oldest data point and add the new one
24-
else
25-
{
23+
else {
2624
m_sum = m_sum - m_readings[m_next] + newReading;
2725
}
2826

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

38+
// return the average for a subset of the data, the most recent nPoints readings.
39+
// for invalid values of nPoints, just return the overall average.
40+
int movingAvg::getAvg(int nPoints)
41+
{
42+
if (nPoints < 1 || nPoints > m_interval - 1) {
43+
return (m_sum + m_nbrReadings / 2) / m_nbrReadings;
44+
}
45+
else {
46+
long sum {0};
47+
for (int i=m_nbrReadings-1; i>=m_nbrReadings-nPoints; --i) {
48+
sum += m_readings[i];
49+
}
50+
return (sum + nPoints / 2) / nPoints;
51+
}
52+
}
53+
4054
// start the moving average over again
4155
void movingAvg::reset()
4256
{

src/movingAvg.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class movingAvg
1414
void begin();
1515
int reading(int newReading);
1616
int getAvg();
17+
int getAvg(int nPoints);
1718
int getCount() {return m_nbrReadings;}
1819
void reset();
1920
int* getReadings() {return m_readings;}

0 commit comments

Comments
 (0)