diff --git a/LICENSE b/LICENSE index 3d51ae3..4c3eaf9 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020 Rob Tillaart +Copyright (c) 2012-2020 Rob Tillaart Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index c2f2a01..946f9a4 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,19 @@ # RunningAverage + Arduino library to calculate the running average by means of a circular buffer. + +## Description +The RunningAverage object gives a running average of the last N numbers, giving them +all equal weight. This is doen by adding new data to an internal circular buffer, +removing the oldest and replace it by the newest. The size of the internal buffer + +By keeping track of the **_sum** the runningAverage can be calculated fast (only 1 division). +This is done with **getFastAverage()**. +However the constant adding/subtracting when adding new elements introduces an accumulating error. +In tests adding up to 1500000 numbers this error was always small. But that is no proof. +In version 0.2.16 there is a fix added that uses the calculation of the sum in **getAverage()** to +update the internal **_sum**. + +## Operation + +See examples diff --git a/RunningAverage.cpp b/RunningAverage.cpp new file mode 100644 index 0000000..de667aa --- /dev/null +++ b/RunningAverage.cpp @@ -0,0 +1,200 @@ +// +// FILE: RunningAverage.cpp +// AUTHOR: Rob Tillaart +// VERSION: 0.2.16 +// DATE: 2015-July-10 +// PURPOSE: RunningAverage library for Arduino +// +// The library stores N individual values in a circular buffer, +// to calculate the running average. +// +// HISTORY: +// 0.1.00 - 2011-01-30 initial version +// 0.1.01 - 2011-02-28 fixed missing destructor in .h +// 0.2.00 - 2012-??-?? Yuval Naveh added trimValue (found on web) +// http://stromputer.googlecode.com/svn-history/r74/trunk/Arduino/Libraries/RunningAverage/RunningAverage.cpp +// 0.2.01 - 2012-11-21 refactored +// 0.2.02 - 2012-12-30 refactored trimValue -> fillValue +// 0.2.03 - 2013-11-31 getElement +// 0.2.04 - 2014-07-03 added memory protection +// 0.2.05 - 2014-12-16 changed float -> double +// 0.2.06 - 2015-03-07 all size uint8_t +// 0.2.07 - 2015-03-16 added getMin() and getMax() functions (Eric Mulder) +// 0.2.08 - 2015-04-10 refactored getMin() and getMax() implementation +// 0.2.09 - 2015-07-12 refactor const + constructor +// 0.2.10 - 2015-09-01 added getFastAverage() and refactored getAverage() +// http://forum.arduino.cc/index.php?topic=50473 +// 0.2.11 - 2015-09-04 added getMaxInBuffer() getMinInBuffer() request (Antoon) +// 0.2.12 - 2016-12-01 added GetStandardDeviation() GetStandardError() BufferIsFull() (V0v1kkk) +// 0.2.13 - 2017-07-26 revert double to float - issue #33; +// refactored a bit; marked some TODO's; all function names to camelCase +// 0.2.14 - 2020-01-15 added getValue(n) to retrieve elements in order of addition - see issue #132 +// 0.2.15 - 2020-01-17 fix overflow in getValue - see issue #139 +// 0.2.16 2020-04-16 improve _sum - see issue #149 (bourkemcrobbo) +// +// Released to the public domain +// + +#include "RunningAverage.h" + +RunningAverage::RunningAverage(const uint8_t size) +{ + _size = size; + _ar = (float*) malloc(_size * sizeof(float)); + if (_ar == NULL) _size = 0; + clear(); +} + +RunningAverage::~RunningAverage() +{ + if (_ar != NULL) free(_ar); +} + +// resets all counters +void RunningAverage::clear() +{ + _cnt = 0; + _idx = 0; + _sum = 0.0; + _min = NAN; + _max = NAN; + for (uint8_t i = _size; i > 0; ) + { + _ar[--i] = 0.0; // keeps addValue simpler + } +} + +// adds a new value to the data-set +void RunningAverage::addValue(const float value) +{ + if (_ar == NULL) return; // allocation error + + _sum -= _ar[_idx]; + _ar[_idx] = value; + _sum += _ar[_idx]; + _idx++; + + if (_idx == _size) _idx = 0; // faster than % + + // handle min max + if (_cnt == 0) _min = _max = value; + else if (value < _min) _min = value; + else if (value > _max) _max = value; + + // update count as last otherwise if ( _cnt == 0) above will fail + if (_cnt < _size) _cnt++; +} + +// returns the average of the data-set added sofar +float RunningAverage::getAverage() +{ + if (_cnt == 0) return NAN; + + _sum = 0; + for (uint8_t i = 0; i < _cnt; i++) + { + _sum += _ar[i]; + } + return _sum / _cnt; // multiplication is faster ==> extra admin +} + +// the larger the size of the internal buffer the greater the gain wrt getAverage() +float RunningAverage::getFastAverage() const +{ + if (_cnt == 0) return NAN; + + return _sum / _cnt; // multiplication is faster ==> extra admin +} + +// returns the minimum value in the buffer +float RunningAverage::getMinInBuffer() const +{ + if (_cnt == 0) return NAN; + + float min = _ar[0]; + for (uint8_t i = 1; i < _cnt; i++) + { + if (_ar[i] < min) min = _ar[i]; + } + return min; +} + +// returns the maximum value in the buffer +float RunningAverage::getMaxInBuffer() const +{ + if (_cnt == 0) return NAN; + + float max = _ar[0]; + for (uint8_t i = 1; i < _cnt; i++) + { + if (_ar[i] > max) max = _ar[i]; + } + return max; +} + + +// returns the value of an element if exist, NAN otherwise +float RunningAverage::getElement(uint8_t idx) const +{ + if (idx >=_cnt ) return NAN; + + return _ar[idx]; +} + +// Return standard deviation of running average. If buffer is empty, return NAN. +float RunningAverage::getStandardDeviation() const +{ + if (_cnt <= 1) return NAN; + + float temp = 0; + float average = getFastAverage(); + for (uint8_t i = 0; i < _cnt; i++) + { + temp += pow((_ar[i] - average), 2); + } + temp = sqrt(temp/(_cnt - 1)); // TODO possible divide by zero .... + + return temp; +} + +// Return standard error of running average. If buffer is empty, return NAN. +float RunningAverage::getStandardError() const //++ +{ + float temp = getStandardDeviation(); + + if (temp == NAN) return NAN; + if (_cnt <= 1) return NAN; + + float n; + if (_cnt >= 30) n = _cnt; + else n = _cnt - 1; + temp = temp/sqrt(n); + + return temp; +} + +// fill the average with the same value number times. (weight) +// This is maximized to size times. no need to fill the internal buffer over 100% +void RunningAverage::fillValue(const float value, const uint8_t number) +{ + clear(); + uint8_t s = number; + if (s > _size) s = _size; + for (uint8_t i = s; i > 0; i--) + { + addValue(value); + } + // NOTE: the clear iterates over the buffer, + // so merging the clear loop could gain some performance. +} + +float RunningAverage::getValue(const uint8_t idx) +{ + if (_cnt == 0) return NAN; + if (idx >= _cnt) return NAN; // cannot ask more than is added + uint16_t pos = idx + _idx; + if (pos >= _cnt) pos -= _cnt; + return _ar[pos]; +} + +// -- END OF FILE -- diff --git a/RunningAverage.h b/RunningAverage.h new file mode 100644 index 0000000..e4282fd --- /dev/null +++ b/RunningAverage.h @@ -0,0 +1,64 @@ +#pragma once +// +// FILE: RunningAverage.h +// AUTHOR: Rob.Tillaart@gmail.com +// VERSION: 0.3.0 +// DATE: 2016-dec-01 +// PURPOSE: RunningAverage library for Arduino +// URL: https://github.com/RobTillaart/RunningAverage +// HISTORY: See RunningAverage.cpp +// + +#define RUNNINGAVERAGE_LIB_VERSION "0.3.0" + +// #include +// #include +#include "Arduino.h" + +class RunningAverage +{ +public: + RunningAverage(void); + explicit RunningAverage(const uint8_t size); + ~RunningAverage(); + + void clear(); + void addValue(const float); + void fillValue(const float, const uint8_t); + float getValue(const uint8_t); + + float getAverage(); // iterates over all elements. + float getFastAverage() const; // reuses previous calculated values. + + // return statistical characteristics of the running average + float getStandardDeviation() const; + float getStandardError() const; + + // returns min/max added to the data-set since last clear + float getMin() const { return _min; }; + float getMax() const { return _max; }; + + // returns min/max from the values in the internal buffer + float getMinInBuffer() const; + float getMaxInBuffer() const; + + // return true if buffer is full + bool bufferIsFull() const { return _cnt == _size; }; + + float getElement(uint8_t idx) const; + + uint8_t getSize() const { return _size; } + uint8_t getCount() const { return _cnt; } + + +protected: + uint8_t _size; + uint8_t _cnt; + uint8_t _idx; + float _sum; + float* _ar; + float _min; + float _max; +}; + +// -- END OF FILE -- diff --git a/examples/fillValue/fillValue.ino b/examples/fillValue/fillValue.ino new file mode 100644 index 0000000..5fe544f --- /dev/null +++ b/examples/fillValue/fillValue.ino @@ -0,0 +1,61 @@ +// +// FILE: fillValue.ino +// AUTHOR: Rob Tillaart +// DATE: 2012-12-30 +// +// PUPROSE: demo + timing of fillValue +// + +#include "RunningAverage.h" + +RunningAverage myRA(10); +int samples = 0; + +uint32_t start, stop; + + +void setup(void) +{ + Serial.begin(115200); + Serial.print("Demo RunningAverage lib - fillValue "); + Serial.print("Version: "); + Serial.println(RUNNINGAVERAGE_LIB_VERSION); + delay(10); + + for (int i = 0; i < 15; i++) + { + measure_duration(i); + } + + Serial.println(); +} + +void loop(void) +{ + long rn = random(0, 100); + myRA.addValue(rn / 100.0); + samples++; + Serial.print("Running Average: "); + Serial.println(myRA.getAverage(), 4); + + if (samples == 300) + { + samples = 0; + myRA.fillValue(100, 10); + } + delay(100); +} + +void measure_duration(int n) +{ + start = micros(); + myRA.fillValue(100, n); + stop = micros(); + Serial.print("fillValue(100, "); + Serial.print(n); + Serial.print("): "); + Serial.println(stop - start); + delay(10); +} + +// -- END OF FILE -- diff --git a/examples/ra_FastAverageTest/ra_FastAverageTest.ino b/examples/ra_FastAverageTest/ra_FastAverageTest.ino new file mode 100644 index 0000000..84ebd51 --- /dev/null +++ b/examples/ra_FastAverageTest/ra_FastAverageTest.ino @@ -0,0 +1,93 @@ +// +// FILE: ra_FastAverageTest.ino +// AUTHOR: Rob Tillaart +// VERSION: 0.2.0 +// DATE: 2015-sep-04 +// +// PUPROSE: demo to see if different average algorithm give different result +// + +#include "RunningAverage.h" + +RunningAverage myRA(16); + +float avg = 0; +float favg = 0; +float diff = 0; +float maxDiff = 0; + +uint32_t start, stop; + +void setup(void) +{ + Serial.begin(115200); + Serial.print("\nDemo "); + Serial.println(__FILE__); + Serial.print("Version: "); + Serial.println(RUNNINGAVERAGE_LIB_VERSION); + myRA.clear(); // explicitly start clean + + measure_duration(); +} + +void loop() +{ + test(1000000); +} + + +void measure_duration() +{ + myRA.fillValue(100, 16); + start = micros(); + favg = myRA.getFastAverage(); + stop = micros(); + Serial.print("getFastAverage: "); + Serial.println(stop - start); + delay(10); + + myRA.fillValue(100, 16); + start = micros(); + favg = myRA.getAverage(); + stop = micros(); + Serial.print(" getAverage: "); + Serial.println(stop - start); + delay(10); + Serial.println(); +} + + + +void test(long n) +{ + Serial.println("\nCNT\tAVG\t\tFASTAVG\t\tDIFF\t\tMAXDIFF"); + + for (long i = 0; i < n; i++) + { + long rn = random(0, 1000); + myRA.addValue(rn * 0.001); + if ( i % 1000 == 0) + { + // the order of the next two lines is important as getAverage() resets the _sum + // used by the getFastAverage(); + favg = myRA.getFastAverage(); + avg = myRA.getAverage(); + diff = abs(avg - favg); + if (diff > maxDiff) maxDiff = diff; + + Serial.print(i); + Serial.print("\t"); + Serial.print(avg, 7); + Serial.print("\t"); + Serial.print(favg, 7); + Serial.print("\t"); + Serial.print(diff, 7); + Serial.print("\t"); + Serial.print(maxDiff, 7); + Serial.println(); + } + } + delay(100); +} + +// -- END OF FILE -- diff --git a/examples/ra_MinMaxBufferTest/ra_MinMaxBufferTest.ino b/examples/ra_MinMaxBufferTest/ra_MinMaxBufferTest.ino new file mode 100644 index 0000000..f71978e --- /dev/null +++ b/examples/ra_MinMaxBufferTest/ra_MinMaxBufferTest.ino @@ -0,0 +1,49 @@ +// +// FILE: ra_MinMaxBufferTest.ino +// AUTHOR: Rob Tillaart +// VERSION: 0.1.00 +// DATE: 2015-SEP-04 +// +// PUPROSE: demo +// + +#include "RunningAverage.h" + +RunningAverage myRA(10); +int samples = 0; + +void setup(void) +{ + Serial.begin(115200); + Serial.print("\nDemo "); + Serial.println(__FILE__); + Serial.print("Version: "); + Serial.println(RUNNINGAVERAGE_LIB_VERSION); + myRA.clear(); // explicitly start clean + + Serial.println("\nCNT\tMIN\tMINBUF\tMAX\tMAXBUF"); +} + +void loop(void) +{ + long rn = random(0, 1000); + myRA.addValue(rn * 0.001); + samples++; + Serial.print(samples); + Serial.print("\t"); + Serial.print(myRA.getMin(), 3); + Serial.print("\t"); + Serial.print(myRA.getMinInBuffer(), 3); + Serial.print("\t"); + Serial.print(myRA.getMaxInBuffer(), 3); + Serial.print("\t"); + Serial.print(myRA.getMax(), 3); + Serial.println(); + if (samples == 100) + { + samples = 0; + myRA.clear(); + Serial.println("\nCNT\tMIN\tMINBUF\tMAX\tMAXBUF"); + } + delay(10); +} \ No newline at end of file diff --git a/examples/ra_MinMaxTest/ra_MinMaxTest.ino b/examples/ra_MinMaxTest/ra_MinMaxTest.ino new file mode 100644 index 0000000..437251a --- /dev/null +++ b/examples/ra_MinMaxTest/ra_MinMaxTest.ino @@ -0,0 +1,46 @@ +// +// FILE: runningAverageMinMaxTest.ino +// AUTHOR: Rob Tillaart +// VERSION: 0.1.00 +// DATE: 2015-apr-10 +// +// PUPROSE: demo +// + +#include "RunningAverage.h" + +RunningAverage myRA(10); +int samples = 0; + +void setup(void) +{ + Serial.begin(115200); + Serial.println("\nDemo runningAverageMinMaxTest"); + Serial.print("Version: "); + Serial.println(RUNNINGAVERAGE_LIB_VERSION); + myRA.clear(); // explicitly start clean + + Serial.println("\nCNT\tMIN\tAVG\tMAX"); +} + +void loop(void) +{ + long rn = random(0, 1000); + myRA.addValue(rn * 0.001); + samples++; + Serial.print(samples); + Serial.print("\t"); + Serial.print(myRA.getMin(), 3); + Serial.print("\t"); + Serial.print(myRA.getAverage(), 3); + Serial.print("\t"); + Serial.println(myRA.getMax(), 3); + + if (samples == 100) + { + samples = 0; + myRA.clear(); + Serial.println("\nCNT\tMIN\tAVG\tMAX"); + } + delay(10); +} diff --git a/examples/ra_getValue/ra_getValue.ino b/examples/ra_getValue/ra_getValue.ino new file mode 100644 index 0000000..e3658d4 --- /dev/null +++ b/examples/ra_getValue/ra_getValue.ino @@ -0,0 +1,69 @@ +// +// FILE: ra_getValue.ino +// AUTHOR: Rob Tillaart +// VERSION: 0.1.0 +// DATE: 2020-01-15 +// +// PUPROSE: demonstrate access in order of the values added +// + +#include "RunningAverage.h" + +RunningAverage myRA(10); +int samples = 0; + +void setup(void) +{ + Serial.begin(115200); + Serial.println("Demo RunningAverage lib"); + Serial.print("Version: "); + Serial.println(RUNNINGAVERAGE_LIB_VERSION); + myRA.clear(); // explicitly start clean +} + +void loop(void) +{ + Serial.println(); + + myRA.clear(); + for (int i = 0; i < 7; i++) + { + myRA.addValue(i); + } + + Serial.print("\t getValue 0..getCount(): "); + for (int i = 0; i < myRA.getCount(); i++) + { + Serial.print("\t"); + Serial.print(myRA.getValue(i), 0); + } + Serial.println(); + + // note first values (0..2) will be overwritten by 10..12 + myRA.clear(); + for (int i = 0; i < 13; i++) + { + myRA.addValue(i); + } + + Serial.print("\t getValue 0..getCount(): "); + for (int i = 0; i < myRA.getCount(); i++) + { + Serial.print("\t"); + Serial.print(myRA.getValue(i), 0); + } + Serial.println(); + + Serial.print("\t get last 5 elements added: "); + int last = myRA.getCount() - 1; // -1 as first idx == 0 + for (int i = last; i > last - 5 && i >= 0; i--) + { + Serial.print("\t"); + Serial.print(myRA.getValue(i), 0); + } + Serial.println(); + + delay(1000); +} + +// -- END OF FILE -- diff --git a/examples/ra_hour/ra_hour.ino b/examples/ra_hour/ra_hour.ino new file mode 100644 index 0000000..09d9214 --- /dev/null +++ b/examples/ra_hour/ra_hour.ino @@ -0,0 +1,40 @@ +// +// FILE: runningAverageHour.pde +// AUTHOR: Rob Tillaart +// DATE: 2012-12-30 +// +// PUPROSE: show working of runningAverage per hour +// in 2 steps - last minute + last hour +// 3 or more steps also possible +// + +#include "RunningAverage.h" + +RunningAverage raMinute(60); +RunningAverage raHour(60); + +int samples = 0; + +void setup(void) +{ + Serial.begin(115200); + Serial.println("Demo RunningAverage lib - average per minute & hour"); + Serial.print("Version: "); + Serial.println(RUNNINGAVERAGE_LIB_VERSION); + raHour.clear(); + raMinute.clear(); +} + +void loop(void) +{ + long rn = random(0, 100); + raMinute.addValue(rn); + samples++; + + if (samples % 60 == 0) raHour.addValue(raMinute.getAverage()); + + Serial.print(" raMinute: "); + Serial.print(raMinute.getAverage(), 4); + Serial.print(" raHour: "); + Serial.println(raHour.getAverage(), 4); +} \ No newline at end of file diff --git a/examples/ra_performance/ra_performance.ino b/examples/ra_performance/ra_performance.ino new file mode 100644 index 0000000..b196c4b --- /dev/null +++ b/examples/ra_performance/ra_performance.ino @@ -0,0 +1,221 @@ +// +// FILE: ra_performance.ino +// AUTHOR: Rob Tillaart +// VERSION: 0.1.0 +// DATE: 2020-04-16 +// +// PUPROSE: timing of runningAverage +// + +#include "RunningAverage.h" + +RunningAverage myRA(50); +int samples = 0; + +uint32_t start, stop; +volatile float x; + +void setup(void) +{ + Serial.begin(115200); + Serial.print("\nPerformance RunningAverage lib: "); + Serial.println(RUNNINGAVERAGE_LIB_VERSION); + Serial.println(); + + myRA.clear(); // explicitly start clean + + for (int i = 0; i < 10; i++) + { + myRA.addValue(random(1000) * 0.001); + } + + test_clear(); + test_addvalue(); + test_fillValue(); + test_getValue(); + + test_getAverage(); + test_getFastAverage(); + + test_getStandardDeviation(); + test_getStandardError(); + + test_getMin(); + test_getMax(); + test_getMinInBuffer(); + test_getMaxInBuffer(); + + test_bufferIsFull(); + test_getElement(); + + test_getSize(); + test_getCount(); + + Serial.println("\ndone...\n"); +} + +void test_clear(void) +{ + start = micros(); + myRA.clear(); + stop = micros(); + Serial.print("\tclear \t\t: "); + Serial.println(stop - start); + delay(10); +} + +void test_addvalue() +{ + start = micros(); + myRA.addValue(3.1415); + stop = micros(); + Serial.print("\taddValue \t: "); + Serial.println(stop - start); + delay(10); +} + +void test_fillValue() +{ + start = micros(); + myRA.fillValue(1.235, 50); + stop = micros(); + Serial.print("\tfillValue \t: "); + Serial.println(stop - start); + delay(10); +} + +void test_getValue() +{ + start = micros(); + x = myRA.getValue(4); + stop = micros(); + Serial.print("\tgetValue \t: "); + Serial.println(stop - start); + delay(10); +} + +void test_getAverage() +{ + start = micros(); + x = myRA.getAverage(); + stop = micros(); + Serial.print("\tgetAverage \t: "); + Serial.println(stop - start); + delay(10); +} + +void test_getFastAverage() +{ + start = micros(); + x = myRA.getFastAverage(); + stop = micros(); + Serial.print("\tgetFastAverage \t: "); + Serial.println(stop - start); + delay(10); +} + +void test_getStandardDeviation() +{ + start = micros(); + x = myRA.getStandardDeviation(); + stop = micros(); + Serial.print("\tgetStandardDeviation \t: "); + Serial.println(stop - start); + delay(10); +} + +void test_getStandardError() +{ + start = micros(); + x = myRA.getStandardError(); + stop = micros(); + Serial.print("\tgetStandardError \t: "); + Serial.println(stop - start); + delay(10); +} + +void test_getMin() +{ + start = micros(); + x = myRA.getMin(); + stop = micros(); + Serial.print("\tgetMin \t\t: "); + Serial.println(stop - start); + delay(10); +} + +void test_getMax() +{ + start = micros(); + x = myRA.getMax(); + stop = micros(); + Serial.print("\tgetMax \t\t: "); + Serial.println(stop - start); + delay(10); +} + +void test_getMinInBuffer() +{ + start = micros(); + x = myRA.getMinInBuffer(); + stop = micros(); + Serial.print("\tgetMinInBuffer \t: "); + Serial.println(stop - start); + delay(10); +} + +void test_getMaxInBuffer() +{ + start = micros(); + x = myRA.getMaxInBuffer(); + stop = micros(); + Serial.print("\tgetMaxInBuffer \t: "); + Serial.println(stop - start); + delay(10); +} + +void test_bufferIsFull() +{ + start = micros(); + x = myRA.bufferIsFull(); + stop = micros(); + Serial.print("\tbufferIsFull \t: "); + Serial.println(stop - start); + delay(10); +} + +void test_getElement() +{ + start = micros(); + x = myRA.getElement(4); + stop = micros(); + Serial.print("\tgetElement \t: "); + Serial.println(stop - start); + delay(10); +} + +void test_getSize() +{ + start = micros(); + x = myRA.getSize(); + stop = micros(); + Serial.print("\tgetSize \t: "); + Serial.println(stop - start); + delay(10); +} + +void test_getCount() +{ + start = micros(); + x = myRA.getCount(); + stop = micros(); + Serial.print("\tgetCount \t: "); + Serial.println(stop - start); + delay(10); +} + +void loop() +{ +} + +// -- END OF FILE -- diff --git a/examples/ra_test/ra_test.ino b/examples/ra_test/ra_test.ino new file mode 100644 index 0000000..146112e --- /dev/null +++ b/examples/ra_test/ra_test.ino @@ -0,0 +1,40 @@ +// +// FILE: runningAverageTest.pde +// AUTHOR: Rob Tillaart +// VERSION: 0.1.01 +// DATE: 2012-12-30 +// +// PUPROSE: show working of runningAverage +// + +#include "RunningAverage.h" + +RunningAverage myRA(10); +int samples = 0; + +void setup(void) +{ + Serial.begin(115200); + Serial.println("Demo RunningAverage lib"); + Serial.print("Version: "); + Serial.println(RUNNINGAVERAGE_LIB_VERSION); + myRA.clear(); // explicitly start clean +} + +void loop(void) +{ + long rn = random(0, 1000); + myRA.addValue(rn * 0.001); + samples++; + Serial.print(samples); + Serial.print("\t Running Average: "); + Serial.println(myRA.getAverage(), 3); + + if (samples == 300) + { + samples = 0; + myRA.clear(); + Serial.println(); + } + delay(10); +} \ No newline at end of file diff --git a/keywords.txt b/keywords.txt new file mode 100644 index 0000000..b723749 --- /dev/null +++ b/keywords.txt @@ -0,0 +1,27 @@ +# Syntax Coloring Map For RunningAverage + +# Datatypes (KEYWORD1) +RunningAverage KEYWORD1 + +# Methods and Functions (KEYWORD2) +clear KEYWORD2 +addValue KEYWORD2 +getAverage KEYWORD2 +getMin KEYWORD2 +getMax KEYWORD2 +fillValue KEYWORD2 +getElement KEYWORD2 +getSize KEYWORD2 +getCount KEYWORD2 +bufferIsFull() KEYWORD2 +getFastAverage KEYWORD2 +getStandardDeviation KEYWORD2 +getStandardError KEYWORD2 +getMinInBuffer KEYWORD2 +getMaxInBuffer KEYWORD2 +getValue KEYWORD2 + +# Instances (KEYWORD2) + +# Constants (LITERAL1) +RUNNINGAVERAGE_LIB_VERSION LITERAL1 \ No newline at end of file diff --git a/library.json b/library.json new file mode 100644 index 0000000..89eae39 --- /dev/null +++ b/library.json @@ -0,0 +1,24 @@ +{ + "name": "RunningAverage", + "keywords": "running average, moving average, average", + "description": "The library stores the last N individual values in a circular buffer to calculate the running average.", + "authors": + [ + { + "name": "Rob Tillaart", + "email": "Rob.Tillaart@gmail.com", + "maintainer": true + } + ], + "repository": + { + "type": "git", + "url": "https://github.com/RobTillaart/RunningAverage.git" + }, + "version": "0.3.0", + "frameworks": "arduino", + "platforms": "*", + "export": { + "include": "RunningAverage" + } +} diff --git a/library.properties b/library.properties new file mode 100644 index 0000000..a328622 --- /dev/null +++ b/library.properties @@ -0,0 +1,11 @@ +name=RunningAverage +version=0.3.0 +author=Rob Tillaart +maintainer=Rob Tillaart +sentence=The library stores the last N individual values in a circular buffer to calculate the running average. +paragraph=Supports min max average +category=Data Processing +url=https://github.com/RobTillaart/RunningAverage +architectures=* +includes=RunningAverager.h +depends= diff --git a/performance.txt b/performance.txt new file mode 100644 index 0000000..c725453 --- /dev/null +++ b/performance.txt @@ -0,0 +1,28 @@ + +-------------------------------------- + +Arduino UNO +IDE 1.8.12 + +Performance RunningAverage lib: 0.3.0 + + clear : 80 + addValue : 24 + fillValue : 1548 + getValue : 4 + getAverage : 512 + getFastAverage : 36 + getStandardDeviation : 1832 + getStandardError : 1896 + getMin : 4 + getMax : 4 + getMinInBuffer : 212 + getMaxInBuffer : 204 + bufferIsFull : 8 + getElement : 4 + getSize : 8 + getCount : 8 + +done... + +-------------------------------------- \ No newline at end of file