mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-09-20 00:55:58 -04:00
eba3ece14e
+ getSize() + getCount() + ifdef conditional to keep code small
135 lines
2.7 KiB
C++
135 lines
2.7 KiB
C++
//
|
|
// FILE: RunningMedian.cpp
|
|
// AUTHOR: Rob dot Tillaart at gmail dot com
|
|
// VERSION: 0.1.04
|
|
// PURPOSE: RunningMedian library for Arduino
|
|
//
|
|
// HISTORY:
|
|
// 0.1.00 - 2011-02-16 initial version
|
|
// 0.1.01 - 2011-02-22 added remarks from CodingBadly
|
|
// 0.1.02 - 2012-03-15 added
|
|
// 0.1.03 - 2013-09-30 added _sorted flag, minor refactor
|
|
// 0.1.04 - 2013-10-17 added getAverage(uint8_t) - kudo's to Sembazuru
|
|
//
|
|
// Released to the public domain
|
|
//
|
|
|
|
#include "RunningMedian.h"
|
|
|
|
RunningMedian::RunningMedian(uint8_t size)
|
|
{
|
|
_size = constrain(size, MEDIAN_MIN_SIZE, MEDIAN_MAX_SIZE);
|
|
// array's could be allocated by malloc here,
|
|
// but using fixed size is easier.
|
|
clear();
|
|
}
|
|
|
|
RunningMedian::RunningMedian()
|
|
{
|
|
_size = MEDIAN_DEF_SIZE;
|
|
clear();
|
|
}
|
|
// resets all counters
|
|
void RunningMedian::clear()
|
|
{
|
|
_cnt = 0;
|
|
_idx = 0;
|
|
_sorted = false;
|
|
}
|
|
|
|
// adds a new value to the data-set
|
|
// or overwrites the oldest if full.
|
|
void RunningMedian::add(float value)
|
|
{
|
|
_ar[_idx++] = value;
|
|
if (_idx >= _size) _idx = 0; // wrap around
|
|
if (_cnt < _size) _cnt++;
|
|
_sorted = false;
|
|
}
|
|
|
|
float RunningMedian::getMedian()
|
|
{
|
|
if (_cnt > 0)
|
|
{
|
|
if (_sorted == false) sort();
|
|
return _as[_cnt/2];
|
|
}
|
|
return NAN;
|
|
}
|
|
|
|
#ifdef RUNNING_MEDIAN_ALL
|
|
float RunningMedian::getHighest()
|
|
{
|
|
if (_cnt > 0)
|
|
{
|
|
if (_sorted == false) sort();
|
|
return _as[_cnt-1];
|
|
}
|
|
return NAN;
|
|
}
|
|
|
|
float RunningMedian::getLowest()
|
|
{
|
|
if (_cnt > 0)
|
|
{
|
|
if (_sorted == false) sort();
|
|
return _as[0];
|
|
}
|
|
return NAN;
|
|
}
|
|
|
|
float RunningMedian::getAverage()
|
|
{
|
|
if (_cnt > 0)
|
|
{
|
|
float sum = 0;
|
|
for (uint8_t i=0; i< _cnt; i++) sum += _ar[i];
|
|
return sum / _cnt;
|
|
}
|
|
return NAN;
|
|
}
|
|
|
|
float RunningMedian::getAverage(uint8_t nMedians)
|
|
{
|
|
if ((_cnt > 0) && (nMedians > 0))
|
|
{
|
|
if (_cnt < nMedians) nMedians = _cnt; // when filling the array for first time
|
|
uint8_t start = ((_cnt - nMedians)/2);
|
|
uint8_t stop = start + nMedians;
|
|
sort();
|
|
float sum = 0;
|
|
for (uint8_t i = start; i < stop; i++) sum += _as[i];
|
|
return sum / nMedians;
|
|
}
|
|
return NAN;
|
|
}
|
|
|
|
uint8_t RunningMedian::getSize() { return _size; };
|
|
|
|
uint8_t RunningMedian::getCount() { return _cnt; };
|
|
#endif
|
|
|
|
void RunningMedian::sort()
|
|
{
|
|
// copy
|
|
for (uint8_t i=0; i< _cnt; i++) _as[i] = _ar[i];
|
|
|
|
// sort all
|
|
for (uint8_t i=0; i< _cnt-1; i++)
|
|
{
|
|
uint8_t m = i;
|
|
for (uint8_t j=i+1; j< _cnt; j++)
|
|
{
|
|
if (_as[j] < _as[m]) m = j;
|
|
}
|
|
if (m != i)
|
|
{
|
|
long t = _as[m];
|
|
_as[m] = _as[i];
|
|
_as[i] = t;
|
|
}
|
|
}
|
|
_sorted = true;
|
|
}
|
|
|
|
// END OF FILE
|