Skip to content

Commit 63dfeb5

Browse files
committed
Add an optional parameter to the constructor to cause getAvg()
to return zero instead of causing a divide-by-zero situation if it is called before any readings are recorded.
1 parent 23290e2 commit 63dfeb5

File tree

4 files changed

+21
-11
lines changed

4 files changed

+21
-11
lines changed

README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,15 @@ along with this program. If not, see <https://www.gnu.org/licenses/gpl.html>
2020
The user specifies the interval (number of data points) for the moving average in the constructor. When the `begin()` function is called, an array is dynamically allocated to hold the number of data points in the interval. This array is never deallocated, and the user should call `begin()` only once (for a given `movingAvg` instance) in setup or other initialization code. Dynamic allocation is used strictly with the intent of creating the proper size array for the user's purposes, and not to free up the memory at a later point. It is strongly recommended that `movingAvg` objects remain allocated as long as the code is running. Failure to observe these guidelines can result in heap fragmentation, crashes and other undesired behavior.
2121

2222
## Constructor
23-
### movingAvg(int interval)
23+
### movingAvg(int interval, bool avoidDivByZero=false)
2424
##### Description
2525
Defines a `movingAvg` object where the average is calculated using *interval* data points.
2626
##### Syntax
2727
`movingAvg(interval);`
2828
##### Parameters
29-
**interval:** The number of data points to use when calculating the moving average. *(int)*
29+
**interval:** The number of data points to use when calculating the moving average. *(int)*
30+
31+
**avoidDivByZero:** Optional parameter that causes `getAvg()` ([see caution below](#getavg)) to return zero if called before any readings are recorded. *(bool, defaults to false if not given)*
3032
##### Returns
3133
None.
3234
##### Example
@@ -53,6 +55,7 @@ mySensor.begin();
5355
### reading(int dataPoint)
5456
##### Description
5557
Adds a new data point to the moving average. Returns the new moving average value. Until the interval array is filled, the average is calculated from those data points already added, i.e. a fewer number of points than defined by the constructor - thanks to Tom H. (Duckie) for this idea!
58+
5659
##### Syntax
5760
`reading(dataPoint);`
5861
##### Parameters
@@ -68,6 +71,8 @@ int sensorMovingAvg = mySensor.reading(sensorData);
6871
### getAvg()
6972
##### Description
7073
Returns the current moving average value without adding a new reading.
74+
75+
**Caution:** If `getAvg()` is called before any data points (readings) are recorded, a divide-by-zero situation will occur, likely with unpredictable/undesirable results. To instead have `getAvg()` return a value of zero in this case, set the optional `avoidDivByZero` parameter in the [constructor](#movingavgint-interval-bool-avoiddivbyzerofalse) to `true`. Note that this may require the caller to implement additional logic to differentiate between a "no data" situation and one where the average is actually zero.
7176
##### Syntax
7277
`getAvg();`
7378
##### Parameters

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=movingAvg
2-
version=2.3.1
2+
version=2.3.2
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.

src/movingAvg.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@ int movingAvg::reading(int newReading)
3232
// just return the current moving average
3333
int movingAvg::getAvg()
3434
{
35-
return (m_sum + m_nbrReadings / 2) / m_nbrReadings;
35+
if (m_nbrReadings || !m_avoidDivByZero)
36+
return (m_sum + m_nbrReadings / 2) / m_nbrReadings;
37+
else
38+
return 0;
3639
}
3740

3841
// return the average for a subset of the data, the most recent nPoints readings.

src/movingAvg.h

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@
99
class movingAvg
1010
{
1111
public:
12-
movingAvg(int interval)
13-
: m_interval{interval}, m_nbrReadings{0}, m_sum{0}, m_next{0} {}
12+
movingAvg(int interval, bool avoidDivByZero=false)
13+
: m_interval{interval}, m_avoidDivByZero{avoidDivByZero},
14+
m_nbrReadings{0}, m_sum{0}, m_next{0} {}
1415
void begin();
1516
int reading(int newReading);
1617
int getAvg();
@@ -20,10 +21,11 @@ class movingAvg
2021
int* getReadings() {return m_readings;}
2122

2223
private:
23-
int m_interval; // number of data points for the moving average
24-
int m_nbrReadings; // number of readings
25-
long m_sum; // sum of the m_readings array
26-
int m_next; // index to the next reading
27-
int* m_readings; // pointer to the dynamically allocated interval array
24+
int m_interval; // number of data points for the moving average
25+
bool m_avoidDivByZero; // return a zero average if requested when there are no data points
26+
int m_nbrReadings; // number of readings
27+
long m_sum; // sum of the m_readings array
28+
int m_next; // index to the next reading
29+
int* m_readings; // pointer to the dynamically allocated interval array
2830
};
2931
#endif

0 commit comments

Comments
 (0)