mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
0.1.0 RunAvgWeight
This commit is contained in:
parent
668c7ce8cf
commit
272cd7e583
29
libraries/RunAvgWeight/.arduino-ci.yml
Normal file
29
libraries/RunAvgWeight/.arduino-ci.yml
Normal file
@ -0,0 +1,29 @@
|
||||
platforms:
|
||||
rpipico:
|
||||
board: rp2040:rp2040:rpipico
|
||||
package: rp2040:rp2040
|
||||
gcc:
|
||||
features:
|
||||
defines:
|
||||
- ARDUINO_ARCH_RP2040
|
||||
warnings:
|
||||
flags:
|
||||
|
||||
packages:
|
||||
rp2040:rp2040:
|
||||
url: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
|
||||
|
||||
compile:
|
||||
# Choosing to run compilation tests on 2 different Arduino platforms
|
||||
# selected only those that work
|
||||
platforms:
|
||||
- uno
|
||||
# - due
|
||||
# - zero
|
||||
# - leonardo
|
||||
- m4
|
||||
- esp32
|
||||
- esp8266
|
||||
# - mega2560
|
||||
- rpipico
|
||||
|
4
libraries/RunAvgWeight/.github/FUNDING.yml
vendored
Normal file
4
libraries/RunAvgWeight/.github/FUNDING.yml
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: RobTillaart
|
||||
custom: "https://www.paypal.me/robtillaart"
|
13
libraries/RunAvgWeight/.github/workflows/arduino-lint.yml
vendored
Normal file
13
libraries/RunAvgWeight/.github/workflows/arduino-lint.yml
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
name: Arduino-lint
|
||||
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: arduino/arduino-lint-action@v1
|
||||
with:
|
||||
library-manager: update
|
||||
compliance: strict
|
17
libraries/RunAvgWeight/.github/workflows/arduino_test_runner.yml
vendored
Normal file
17
libraries/RunAvgWeight/.github/workflows/arduino_test_runner.yml
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
name: Arduino CI
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
runTest:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: 2.6
|
||||
- run: |
|
||||
gem install arduino_ci
|
||||
arduino_ci.rb
|
18
libraries/RunAvgWeight/.github/workflows/jsoncheck.yml
vendored
Normal file
18
libraries/RunAvgWeight/.github/workflows/jsoncheck.yml
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
name: JSON check
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '**.json'
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: json-syntax-check
|
||||
uses: limitusus/json-syntax-check@v2
|
||||
with:
|
||||
pattern: "\\.json$"
|
11
libraries/RunAvgWeight/CHANGELOG.md
Normal file
11
libraries/RunAvgWeight/CHANGELOG.md
Normal file
@ -0,0 +1,11 @@
|
||||
# Change Log RunAvgWeight
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
|
||||
## [0.1.0] - 2024-06-30
|
||||
- initial version, based upon **RunningAverage**
|
||||
|
21
libraries/RunAvgWeight/LICENSE
Normal file
21
libraries/RunAvgWeight/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024-2024 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
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
121
libraries/RunAvgWeight/README.md
Normal file
121
libraries/RunAvgWeight/README.md
Normal file
@ -0,0 +1,121 @@
|
||||
|
||||
[![Arduino CI](https://github.com/RobTillaart/RunAvgWeight/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)
|
||||
[![Arduino-lint](https://github.com/RobTillaart/RunAvgWeight/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/RunAvgWeight/actions/workflows/arduino-lint.yml)
|
||||
[![JSON check](https://github.com/RobTillaart/RunAvgWeight/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/RunAvgWeight/actions/workflows/jsoncheck.yml)
|
||||
[![GitHub issues](https://img.shields.io/github/issues/RobTillaart/RunAvgWeight.svg)](https://github.com/RobTillaart/RunAvgWeight/issues)
|
||||
|
||||
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/RunAvgWeight/blob/master/LICENSE)
|
||||
[![GitHub release](https://img.shields.io/github/release/RobTillaart/RunAvgWeight.svg?maxAge=3600)](https://github.com/RobTillaart/RunAvgWeight/releases)
|
||||
[![PlatformIO Registry](https://badges.registry.platformio.org/packages/robtillaart/library/RunAvgWeight.svg)](https://registry.platformio.org/libraries/robtillaart/RunAvgWeight)
|
||||
|
||||
|
||||
# RunAvgWeight
|
||||
|
||||
Arduino library to calculate the running average with weights by means of a circular buffer.
|
||||
|
||||
|
||||
## Description
|
||||
|
||||
**Experimental**
|
||||
|
||||
The RunAvgWeight (RAW) object gives a running average of the last N floating point numbers,
|
||||
while giving them a different weight.
|
||||
|
||||
This is done by adding new data to internal circular buffers, removing the oldest and
|
||||
replace it by the newest.
|
||||
The size of the internal buffer can be set in the constructor.
|
||||
|
||||
The interface of the RunAvgWeight object is strongly based upon **RunningAverage**.
|
||||
However not all functions are implemented.
|
||||
|
||||
**Warning**
|
||||
|
||||
However the constant adding and subtracting when adding new elements to the RAW object
|
||||
possibly introduces an ever increasing error.
|
||||
In tests with **RunningAverage** class with equal weights, adding up to 1500000 numbers
|
||||
this error was always small. Be aware of this.
|
||||
|
||||
|
||||
#### Related
|
||||
|
||||
- https://github.com/RobTillaart/Correlation
|
||||
- https://github.com/RobTillaart/GST - Golden standard test metrics
|
||||
- https://github.com/RobTillaart/Histogram
|
||||
- https://github.com/RobTillaart/RunningAngle
|
||||
- https://github.com/RobTillaart/RunAvgWeight
|
||||
- https://github.com/RobTillaart/RunningAverage
|
||||
- https://github.com/RobTillaart/RunningMedian
|
||||
- https://github.com/RobTillaart/statHelpers - combinations & permutations
|
||||
- https://github.com/RobTillaart/printHelpers - print scientific format
|
||||
- https://github.com/RobTillaart/Statistic
|
||||
|
||||
|
||||
## Interface
|
||||
|
||||
```cpp
|
||||
#include "RunAvgWeight.h"
|
||||
```
|
||||
|
||||
### Constructor
|
||||
|
||||
- **RunAvgWeight(uint16_t size)** allocates dynamic memory, one float (4 bytes) per element.
|
||||
No default size (yet).
|
||||
- **~RunAvgWeight()** destructor to free the memory allocated.
|
||||
|
||||
|
||||
### Basic
|
||||
|
||||
- **void clear()** empties the internal buffers.
|
||||
- **void addValue(float value, float weight)** adds a new value to the object,
|
||||
if the internal buffer is full, the oldest element is removed.
|
||||
- **float getValue(uint16_t position)** returns the value at **position** from the additions.
|
||||
Position 0 is the first one to disappear.
|
||||
- **float getAverage()** iterates over all elements to get the average, slower but accurate.
|
||||
Updates the variables used by **getFastAverage()** to improve its accuracy again.
|
||||
- **float getFastAverage()** reuses previous calculated values, therefore faster. Accuracy can drift.
|
||||
|
||||
|
||||
### Extended functions
|
||||
|
||||
- **float getStandardDeviation()** returns the standard deviation of the current content.
|
||||
Needs more than one element to be calculable.
|
||||
- **float getStandardError()** returns the standard error of the current content.
|
||||
- **float getMin()** returns minimum since last clear, does not need to be in the buffer any more.
|
||||
- **float getMax()** returns maximum since last clear, does not need to be in the buffer any more.
|
||||
- **float getMinInBuffer()** returns minimum in the internal buffer.
|
||||
- **float getMaxInBuffer()** returns maximum in the internal buffer.
|
||||
|
||||
|
||||
### Admin functions
|
||||
|
||||
- **bool bufferIsFull()** returns true if buffer is full.
|
||||
- **float getElement(uint16_t index)** get element directly from internal buffer at index. (debug)
|
||||
- **uint16_t getSize()** returns the size of the internal array.
|
||||
- **uint16_t getCount()** returns the number of slots used of the internal array.
|
||||
|
||||
|
||||
|
||||
## Future
|
||||
|
||||
#### Must
|
||||
|
||||
- update documentation
|
||||
- keep in sync with RunningAverage
|
||||
|
||||
#### Should
|
||||
|
||||
- elaborate unit test
|
||||
|
||||
#### Could
|
||||
|
||||
#### Wont
|
||||
|
||||
## Support
|
||||
|
||||
If you appreciate my libraries, you can support the development and maintenance.
|
||||
Improve the quality of the libraries by providing issues and Pull Requests, or
|
||||
donate through PayPal or GitHub sponsors.
|
||||
|
||||
Thank you,
|
||||
|
||||
|
253
libraries/RunAvgWeight/RunAvgWeight.cpp
Normal file
253
libraries/RunAvgWeight/RunAvgWeight.cpp
Normal file
@ -0,0 +1,253 @@
|
||||
//
|
||||
// FILE: RunAvgWeight.cpp
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.0
|
||||
// DATE: 2024-06-30
|
||||
// PURPOSE: Arduino library to calculate the running average with weights by means of a circular buffer
|
||||
// URL: https://github.com/RobTillaart/RunAvgWeight
|
||||
//
|
||||
// based upon: https://github.com/RobTillaart/RunningAverage
|
||||
|
||||
|
||||
#include "RunAvgWeight.h"
|
||||
|
||||
|
||||
RunAvgWeight::RunAvgWeight(const uint16_t size)
|
||||
{
|
||||
_size = size;
|
||||
_values = (float*) malloc(_size * sizeof(float));
|
||||
_weights = (float *) malloc(_size * sizeof(float));
|
||||
if (_values == NULL) _size = 0;
|
||||
if (_weights == NULL) _size = 0;
|
||||
clear();
|
||||
}
|
||||
|
||||
|
||||
RunAvgWeight::~RunAvgWeight()
|
||||
{
|
||||
if (_values != NULL) free(_values);
|
||||
if (_weights != NULL) free(_weights);
|
||||
}
|
||||
|
||||
|
||||
// resets all counters
|
||||
void RunAvgWeight::clear()
|
||||
{
|
||||
_count = 0;
|
||||
_index = 0;
|
||||
_sumValues = 0.0;
|
||||
_sumWeights = 0.0;
|
||||
_min = NAN;
|
||||
_max = NAN;
|
||||
for (uint16_t i = _size; i > 0; )
|
||||
{
|
||||
_values[--i] = 0.0; // keeps addValue simpler
|
||||
_weights[--i] = 0.0; // keeps addValue simpler
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// adds a new value to the data-set
|
||||
void RunAvgWeight::addValue(const float value, const float weight)
|
||||
{
|
||||
if ((_values == NULL) || (_weights == NULL))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_sumValues -= _values[_index];
|
||||
_values[_index] = value;
|
||||
_sumValues += _values[_index];
|
||||
|
||||
_sumWeights -= _weights[_index];
|
||||
_weights[_index] = weight;
|
||||
_sumWeights += _weights[_index];
|
||||
_index++;
|
||||
|
||||
if (_index == _size) _index = 0; // faster than %
|
||||
|
||||
// handle min max
|
||||
if (_count == 0) _min = _max = value;
|
||||
else if (value < _min) _min = value;
|
||||
else if (value > _max) _max = value;
|
||||
|
||||
// update count as last otherwise if ( _count == 0) above will fail
|
||||
if (_count < _size) _count++;
|
||||
}
|
||||
|
||||
|
||||
float RunAvgWeight::getValue(const uint16_t position)
|
||||
{
|
||||
if (_count == 0)
|
||||
{
|
||||
return NAN;
|
||||
}
|
||||
if (position >= _count)
|
||||
{
|
||||
return NAN; // cannot ask more than is added
|
||||
}
|
||||
uint16_t pos = position + _index;
|
||||
if (pos >= _count) pos -= _count;
|
||||
return _values[pos];
|
||||
}
|
||||
|
||||
|
||||
// returns the weight of an element if exist, NAN otherwise
|
||||
// "partner" of getValue()
|
||||
float RunAvgWeight::getWeight(const uint16_t position)
|
||||
{
|
||||
if (_count == 0)
|
||||
{
|
||||
return NAN;
|
||||
}
|
||||
if (position >= _count)
|
||||
{
|
||||
return NAN; // cannot ask more than is added
|
||||
}
|
||||
uint16_t pos = position + _index;
|
||||
if (pos >= _count) pos -= _count;
|
||||
return _weights[pos];
|
||||
}
|
||||
|
||||
|
||||
// returns the average of the data-set added so far, NAN if no elements.
|
||||
float RunAvgWeight::getAverage()
|
||||
{
|
||||
if (_count == 0)
|
||||
{
|
||||
return NAN;
|
||||
}
|
||||
// OPTIMIZE local variable for sums.
|
||||
_sumValues = 0;
|
||||
_sumWeights = 0;
|
||||
for (uint16_t i = 0; i < _count; i++)
|
||||
{
|
||||
_sumValues += _values[i] * _weights[i];
|
||||
_sumWeights += _weights[i];
|
||||
}
|
||||
return _sumValues / _sumWeights; // multiplication is faster ==> extra admin
|
||||
}
|
||||
|
||||
|
||||
// the larger the size of the internal buffer
|
||||
// the greater the gain with respect to getAverage()
|
||||
float RunAvgWeight::getFastAverage()
|
||||
{
|
||||
if (_count == 0)
|
||||
{
|
||||
return NAN;
|
||||
}
|
||||
|
||||
return _sumValues / _sumWeights;
|
||||
}
|
||||
|
||||
|
||||
// returns the minimum value in the buffer
|
||||
float RunAvgWeight::getMinInBuffer()
|
||||
{
|
||||
if (_count == 0)
|
||||
{
|
||||
return NAN;
|
||||
}
|
||||
|
||||
float _min = _values[0];
|
||||
for (uint16_t i = 1; i < _count; i++)
|
||||
{
|
||||
if (_values[i] < _min) _min = _values[i];
|
||||
}
|
||||
return _min;
|
||||
}
|
||||
|
||||
|
||||
// returns the maximum value in the buffer
|
||||
float RunAvgWeight::getMaxInBuffer()
|
||||
{
|
||||
if (_count == 0)
|
||||
{
|
||||
return NAN;
|
||||
}
|
||||
|
||||
float _max = _values[0];
|
||||
for (uint16_t i = 1; i < _count; i++)
|
||||
{
|
||||
if (_values[i] > _max) _max = _values[i];
|
||||
}
|
||||
return _max;
|
||||
}
|
||||
|
||||
|
||||
// returns the value of an element if exist, NAN otherwise
|
||||
float RunAvgWeight::getElementValue(uint16_t index)
|
||||
{
|
||||
if (_count == 0)
|
||||
{
|
||||
return NAN;
|
||||
}
|
||||
return _values[index];
|
||||
}
|
||||
|
||||
|
||||
// returns the value of an element if exist, NAN otherwise
|
||||
float RunAvgWeight::getElementWeight(uint16_t index)
|
||||
{
|
||||
if (_count == 0)
|
||||
{
|
||||
return NAN;
|
||||
}
|
||||
return _weights[index];
|
||||
}
|
||||
|
||||
|
||||
|
||||
// What is standard deviation in weighted average context?
|
||||
// https://en.wikipedia.org/wiki/Weighted_arithmetic_mean#Weighted_sample_variance
|
||||
//
|
||||
// https://stackoverflow.com/questions/61831353/how-can-i-calculate-weighted-standard-errors-and-plot-them-in-a-bar-plot
|
||||
// pop_v = sum( w * (x-mean)^2 ) / sum( w )
|
||||
// if the weights are frequency pop_v = sum( w * (x-mean)^2 ) / (sum( w ) - 1)
|
||||
|
||||
/*
|
||||
weighted.var = function(x,w,type="reliability") {
|
||||
m=weighted.mean(x,w)
|
||||
if(type=="frequency"){ return( sum(w*(x-m)^2)/(sum(w)-1) ) }
|
||||
else { return( sum(w*(x-m)^2)*sum(w)/(sum(w)^2-sum(w^2)) ) }
|
||||
}
|
||||
weighted.sem = function(x,w,...) { return( sqrt(weighted.var(x,w,...)*sum(w^2)/sum(w)^2) ) }
|
||||
*/
|
||||
|
||||
|
||||
// If buffer is empty or has only one element, return NAN.
|
||||
float RunAvgWeight::getStandardDeviation()
|
||||
{
|
||||
if (_count <= 1) return NAN;
|
||||
|
||||
float average = getFastAverage();
|
||||
float variance = 0;
|
||||
for (uint16_t i = 0; i < _count; i++)
|
||||
{
|
||||
float t = _values[i] - average;
|
||||
variance += t * t * _weights[i];
|
||||
}
|
||||
variance /= _sumWeights;
|
||||
return sqrt(variance);
|
||||
}
|
||||
|
||||
// TODO: What is standard error in weighted average context?
|
||||
// see above.
|
||||
// If buffer is empty or has only one element, return NAN.
|
||||
float RunAvgWeight::getStandardError()
|
||||
{
|
||||
float temp = getStandardDeviation();
|
||||
if (temp == NAN) return NAN;
|
||||
|
||||
float n;
|
||||
if (_count >= 30) n = _count;
|
||||
else n = _count - 1;
|
||||
temp = temp/sqrt(n);
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
|
80
libraries/RunAvgWeight/RunAvgWeight.h
Normal file
80
libraries/RunAvgWeight/RunAvgWeight.h
Normal file
@ -0,0 +1,80 @@
|
||||
#pragma once
|
||||
//
|
||||
// FILE: RunAvgWeight.h
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.0
|
||||
// DATE: 2024-06-30
|
||||
// PURPOSE: Arduino library to calculate the running average with weights by means of a circular buffer
|
||||
// URL: https://github.com/RobTillaart/RunAvgWeight
|
||||
//
|
||||
// based upon: https://github.com/RobTillaart/RunningAverage
|
||||
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
|
||||
#define RUNAVGWEIGHT_LIB_VERSION (F("0.1.0"))
|
||||
|
||||
|
||||
class RunAvgWeight
|
||||
{
|
||||
public:
|
||||
explicit RunAvgWeight(const uint16_t size);
|
||||
~RunAvgWeight();
|
||||
|
||||
void clear();
|
||||
void addValue(const float value, const float weight = 1.0);
|
||||
float getValue(const uint16_t position);
|
||||
float getWeight(const uint16_t position);
|
||||
|
||||
// getAverage() iterates over all elements.
|
||||
float getAverage();
|
||||
// getFastAverage() reuses previous calculated values.
|
||||
float getFastAverage();
|
||||
|
||||
// return statistical characteristics of the running average.
|
||||
// TODO: investigate correctness of these two functions.
|
||||
// weight == 1
|
||||
// weight <> 1
|
||||
float getStandardDeviation();
|
||||
float getStandardError();
|
||||
|
||||
// returns min/max added to the data-set since last clear.
|
||||
// values without weight!
|
||||
float getMin() { return _min; };
|
||||
float getMax() { return _max; };
|
||||
|
||||
// returns min/max from the values in the internal buffer.
|
||||
// values without weight!
|
||||
float getMinInBuffer();
|
||||
float getMaxInBuffer();
|
||||
|
||||
// return true if buffer is full
|
||||
bool bufferIsFull() { return _count == _size; };
|
||||
|
||||
// helper functions.
|
||||
float getElementValue(uint16_t index);
|
||||
float getElementWeight(uint16_t index);
|
||||
float getSumValues() { return _sumValues; };
|
||||
float getSumWeights() { return _sumWeights; };
|
||||
|
||||
uint16_t getSize() { return _size; }
|
||||
uint16_t getCount() { return _count; }
|
||||
|
||||
|
||||
protected:
|
||||
uint16_t _size;
|
||||
uint16_t _count;
|
||||
uint16_t _index;
|
||||
|
||||
float * _values;
|
||||
float * _weights;
|
||||
float _sumValues;
|
||||
float _sumWeights;
|
||||
float _min;
|
||||
float _max;
|
||||
};
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
|
@ -0,0 +1,59 @@
|
||||
//
|
||||
// FILE: raw_demo_equal_weight.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// DATE: 2024-06-30
|
||||
// PURPOSE: show working of RunAvgWeight with equal weights
|
||||
// URL: https://github.com/RobTillaart/RunAvgWeight
|
||||
|
||||
|
||||
#include "RunAvgWeight.h"
|
||||
|
||||
|
||||
RunAvgWeight myRA(10);
|
||||
int samples = 0;
|
||||
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println();
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("RUNAVGWEIGHT_LIB_VERSION: ");
|
||||
Serial.println(RUNAVGWEIGHT_LIB_VERSION);
|
||||
|
||||
myRA.clear(); // explicitly start clean
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
myRA.addValue(i * 0.01 + 1 );
|
||||
// Serial.print(myRA.getCount());
|
||||
// Serial.print("\t");
|
||||
// Serial.print(myRA.getAverage(), 3);
|
||||
// Serial.print("\t");
|
||||
Serial.print(myRA.getStandardDeviation(), 3);
|
||||
Serial.print("\t");
|
||||
Serial.println(myRA.getMaxInBuffer(), 3);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
95
libraries/RunAvgWeight/examples/raw_test/raw_test.ino
Normal file
95
libraries/RunAvgWeight/examples/raw_test/raw_test.ino
Normal file
@ -0,0 +1,95 @@
|
||||
//
|
||||
// FILE: raw_test.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// DATE: 2024-06-30
|
||||
// PURPOSE: show working of RunAvgWeight
|
||||
// URL: https://github.com/RobTillaart/RunAvgWeight
|
||||
|
||||
|
||||
#include "RunAvgWeight.h"
|
||||
|
||||
|
||||
RunAvgWeight myRA(10);
|
||||
int samples = 0;
|
||||
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println();
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("RUNAVGWEIGHT_LIB_VERSION: ");
|
||||
Serial.println(RUNAVGWEIGHT_LIB_VERSION);
|
||||
Serial.println();
|
||||
|
||||
myRA.clear(); // explicitly start clean
|
||||
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
float value = i * 0.01 + 1;
|
||||
float weight = sqrt(i);
|
||||
myRA.addValue(value, weight);
|
||||
Serial.print(myRA.bufferIsFull());
|
||||
}
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
Serial.print(i);
|
||||
Serial.print("\t");
|
||||
Serial.print(myRA.getValue(i), 3);
|
||||
Serial.print("\t");
|
||||
Serial.print(myRA.getWeight(i), 3);
|
||||
Serial.println();
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
Serial.print("SIZE:\t");
|
||||
Serial.println(myRA.getSize());
|
||||
Serial.print("COUNT:\t");
|
||||
Serial.println(myRA.getCount());
|
||||
Serial.println();
|
||||
|
||||
Serial.print("AVG:\t");
|
||||
Serial.println(myRA.getAverage(), 5);
|
||||
Serial.print("AVG(f):\t");
|
||||
Serial.println(myRA.getFastAverage(), 5);
|
||||
Serial.println();
|
||||
|
||||
Serial.print("STDDEV:\t");
|
||||
Serial.println(myRA.getStandardDeviation(), 5);
|
||||
Serial.print("ERROR:\t");
|
||||
Serial.println(myRA.getStandardError(), 5);
|
||||
Serial.println();
|
||||
|
||||
Serial.print("MIN:\t");
|
||||
Serial.println(myRA.getMin(), 3);
|
||||
Serial.print("MININB:\t");
|
||||
Serial.println(myRA.getMinInBuffer(), 3);
|
||||
Serial.println();
|
||||
|
||||
Serial.print("MAX:\t");
|
||||
Serial.println(myRA.getMax(), 3);
|
||||
Serial.print("MAXINB:\t");
|
||||
Serial.println(myRA.getMaxInBuffer(), 3);
|
||||
Serial.println();
|
||||
|
||||
Serial.print("SUMVAL:\t");
|
||||
Serial.println(myRA.getSumValues(), 3);
|
||||
Serial.print("SUMWGT:\t");
|
||||
Serial.println(myRA.getSumWeights(), 3);
|
||||
Serial.print("RATIO:\t");
|
||||
Serial.println(myRA.getSumValues() / myRA.getSumWeights(), 3);
|
||||
Serial.println();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
39
libraries/RunAvgWeight/keywords.txt
Normal file
39
libraries/RunAvgWeight/keywords.txt
Normal file
@ -0,0 +1,39 @@
|
||||
# Syntax Colouring Map For RunningAverage
|
||||
|
||||
|
||||
# Data types (KEYWORD1)
|
||||
RunAvgWeight KEYWORD1
|
||||
|
||||
|
||||
# Methods and Functions (KEYWORD2)
|
||||
clear KEYWORD2
|
||||
addValue KEYWORD2
|
||||
getValue KEYWORD2
|
||||
getWeight KEYWORD2
|
||||
|
||||
getAverage KEYWORD2
|
||||
getFastAverage KEYWORD2
|
||||
getStandardDeviation KEYWORD2
|
||||
getStandardError KEYWORD2
|
||||
|
||||
getMin KEYWORD2
|
||||
getMax KEYWORD2
|
||||
getMinInBuffer KEYWORD2
|
||||
getMaxInBuffer KEYWORD2
|
||||
|
||||
bufferIsFull KEYWORD2
|
||||
|
||||
getElementValue KEYWORD2
|
||||
getElementWeight KEYWORD2
|
||||
getSumValues KEYWORD2
|
||||
getSumWeights KEYWORD2
|
||||
|
||||
getSize KEYWORD2
|
||||
getCount KEYWORD2
|
||||
|
||||
|
||||
# Instances (KEYWORD2)
|
||||
|
||||
|
||||
# Constants (LITERAL1)
|
||||
RUNAVGWEIGHT_LIB_VERSION LITERAL1
|
23
libraries/RunAvgWeight/library.json
Normal file
23
libraries/RunAvgWeight/library.json
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "RunAvgWeight",
|
||||
"keywords": "running average, moving average, average",
|
||||
"description": "Running Average with weight of N elements. Supports min max average.",
|
||||
"authors":
|
||||
[
|
||||
{
|
||||
"name": "Rob Tillaart",
|
||||
"email": "Rob.Tillaart@gmail.com",
|
||||
"maintainer": true
|
||||
}
|
||||
],
|
||||
"repository":
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/RobTillaart/RunAvgWeight.git"
|
||||
},
|
||||
"version": "0.1.0",
|
||||
"license": "MIT",
|
||||
"frameworks": "*",
|
||||
"platforms": "*",
|
||||
"headers": "RunAvgWeight.h"
|
||||
}
|
11
libraries/RunAvgWeight/library.properties
Normal file
11
libraries/RunAvgWeight/library.properties
Normal file
@ -0,0 +1,11 @@
|
||||
name=RunAvgWeight
|
||||
version=0.1.0
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
sentence=Running Average with weight of N elements.
|
||||
paragraph=Supports min max average.
|
||||
category=Data Processing
|
||||
url=https://github.com/RobTillaart/RunAvgWeight
|
||||
architectures=*
|
||||
includes=RunAvgWeight.h
|
||||
depends=
|
125
libraries/RunAvgWeight/test/unit_test_001.cpp
Normal file
125
libraries/RunAvgWeight/test/unit_test_001.cpp
Normal file
@ -0,0 +1,125 @@
|
||||
//
|
||||
// FILE: unit_test_001.cpp
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.0
|
||||
// DATE: 2024-06-30
|
||||
// PURPOSE: unit tests for RunAvgWeight
|
||||
// https://github.com/RobTillaart/RunAvgWeight
|
||||
//
|
||||
|
||||
|
||||
// supported assertions
|
||||
// ----------------------------
|
||||
// assertEqual(expected, actual); // a == b
|
||||
// assertNotEqual(unwanted, actual); // a != b
|
||||
// assertComparativeEquivalent(expected, actual); // abs(a - b) == 0 or (!(a > b) && !(a < b))
|
||||
// assertComparativeNotEquivalent(unwanted, actual); // abs(a - b) > 0 or ((a > b) || (a < b))
|
||||
// assertLess(upperBound, actual); // a < b
|
||||
// assertMore(lowerBound, actual); // a > b
|
||||
// assertLessOrEqual(upperBound, actual); // a <= b
|
||||
// assertMoreOrEqual(lowerBound, actual); // a >= b
|
||||
// assertTrue(actual);
|
||||
// assertFalse(actual);
|
||||
// assertNull(actual);
|
||||
|
||||
// // special cases for floats
|
||||
// assertEqualFloat(expected, actual, epsilon); // fabs(a - b) <= epsilon
|
||||
// assertNotEqualFloat(unwanted, actual, epsilon); // fabs(a - b) >= epsilon
|
||||
// assertInfinity(actual); // isinf(a)
|
||||
// assertNotInfinity(actual); // !isinf(a)
|
||||
// assertNAN(arg); // isnan(a)
|
||||
// assertNotNAN(arg); // !isnan(a)
|
||||
|
||||
#include <ArduinoUnitTests.h>
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "RunAvgWeight.h"
|
||||
|
||||
|
||||
unittest_setup()
|
||||
{
|
||||
fprintf(stderr, "RUNAVGWEIGHT_LIB_VERSION: %s\n", (char *) RUNAVGWEIGHT_LIB_VERSION);
|
||||
}
|
||||
|
||||
|
||||
unittest_teardown()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
unittest(test_zero_elements)
|
||||
{
|
||||
RunAvgWeight myRA(10);
|
||||
myRA.clear();
|
||||
|
||||
int size = myRA.getSize();
|
||||
assertEqual(10, size);
|
||||
|
||||
int cnt = myRA.getCount();
|
||||
assertEqual(0, cnt);
|
||||
|
||||
float x = myRA.getAverage();
|
||||
assertNAN(x);
|
||||
}
|
||||
|
||||
|
||||
unittest(test_min_max)
|
||||
{
|
||||
RunAvgWeight myRA(10);
|
||||
myRA.clear();
|
||||
|
||||
for (int i = -5; i < 6; i++)
|
||||
{
|
||||
myRA.addValue(i);
|
||||
}
|
||||
|
||||
float mi = myRA.getMin();
|
||||
assertEqual(-5, mi);
|
||||
float ma = myRA.getMax();
|
||||
assertEqual(5, ma);
|
||||
|
||||
mi = myRA.getMinInBuffer();
|
||||
assertEqual(-4, mi);
|
||||
ma = myRA.getMaxInBuffer();
|
||||
assertEqual(5, ma);
|
||||
}
|
||||
|
||||
|
||||
unittest(test_buffer_full)
|
||||
{
|
||||
RunAvgWeight myRA(10);
|
||||
myRA.clear();
|
||||
assertFalse(myRA.bufferIsFull());
|
||||
|
||||
for (int i = 0; i < 9; i++)
|
||||
{
|
||||
myRA.addValue(i);
|
||||
assertFalse(myRA.bufferIsFull());
|
||||
}
|
||||
|
||||
myRA.addValue(42);
|
||||
assertTrue(myRA.bufferIsFull());
|
||||
}
|
||||
|
||||
|
||||
unittest(test_large)
|
||||
{
|
||||
RunAvgWeight myRA(300);
|
||||
myRA.clear();
|
||||
assertFalse(myRA.bufferIsFull());
|
||||
|
||||
for (int i = 0; i < 299; i++)
|
||||
{
|
||||
myRA.addValue(i);
|
||||
assertFalse(myRA.bufferIsFull());
|
||||
}
|
||||
|
||||
myRA.addValue(42);
|
||||
assertTrue(myRA.bufferIsFull());
|
||||
}
|
||||
|
||||
|
||||
unittest_main()
|
||||
|
||||
|
||||
// --------
|
Loading…
Reference in New Issue
Block a user