mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-09-20 00:55:58 -04:00
+ version 0.1.06
+ dynamic internal buffers + replace sorted buffer with "indirection buffer" + bubble sort + flag (faster)
This commit is contained in:
parent
28b1b43b2a
commit
ff52d49117
@ -11,7 +11,7 @@
|
|||||||
// 0.1.03 - 2013-09-30 added _sorted flag, minor refactor
|
// 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
|
// 0.1.04 - 2013-10-17 added getAverage(uint8_t) - kudo's to Sembazuru
|
||||||
// 0.1.05 - 2013-10-18 fixed bug in sort; removes default constructor; dynamic memory
|
// 0.1.05 - 2013-10-18 fixed bug in sort; removes default constructor; dynamic memory
|
||||||
// 0.1.06 - 2013-10-19 faster sort? more dyn test.
|
// 0.1.06 - 2013-10-19 faster sort, dynamic arrays, replaced sorted float array with indirection array
|
||||||
//
|
//
|
||||||
// Released to the public domain
|
// Released to the public domain
|
||||||
//
|
//
|
||||||
@ -24,7 +24,7 @@ RunningMedian::RunningMedian(uint8_t size)
|
|||||||
|
|
||||||
#ifdef RUNNING_MEDIAN_USE_MALLOC
|
#ifdef RUNNING_MEDIAN_USE_MALLOC
|
||||||
_ar = (float *) malloc(_size * sizeof(float));
|
_ar = (float *) malloc(_size * sizeof(float));
|
||||||
_p = (uint8_t *) malloc(size * sizeof(uint8_t));
|
_p = (uint8_t *) malloc(_size * sizeof(uint8_t));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
@ -45,15 +45,16 @@ void RunningMedian::clear()
|
|||||||
_idx = 0;
|
_idx = 0;
|
||||||
_sorted = false;
|
_sorted = false;
|
||||||
|
|
||||||
// for (uint8_t i=0; i< _size; i++) _p[i] = i;
|
for (uint8_t i=0; i< _size; i++) _p[i] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
// adds a new value to the data-set
|
// adds a new value to the data-set
|
||||||
// or overwrites the oldest if full.
|
// or overwrites the oldest if full.
|
||||||
void RunningMedian::add(float value)
|
void RunningMedian::add(float value)
|
||||||
{
|
{
|
||||||
_ar[_idx++] = value;
|
_idx++;
|
||||||
if (_idx >= _size) _idx = 0; // wrap around
|
if (_idx >= _size) _idx = 0; // wrap around
|
||||||
|
_ar[_idx] = value;
|
||||||
if (_cnt < _size) _cnt++;
|
if (_cnt < _size) _cnt++;
|
||||||
_sorted = false;
|
_sorted = false;
|
||||||
}
|
}
|
||||||
@ -64,7 +65,6 @@ float RunningMedian::getMedian()
|
|||||||
{
|
{
|
||||||
if (_sorted == false) sort();
|
if (_sorted == false) sort();
|
||||||
return _ar[_p[_cnt/2]];
|
return _ar[_p[_cnt/2]];
|
||||||
// return _as[_cnt/2];
|
|
||||||
}
|
}
|
||||||
return NAN;
|
return NAN;
|
||||||
}
|
}
|
||||||
@ -74,9 +74,8 @@ float RunningMedian::getHighest()
|
|||||||
{
|
{
|
||||||
if (_cnt > 0)
|
if (_cnt > 0)
|
||||||
{
|
{
|
||||||
if (_sorted == false) sort();
|
if (_sorted == false) sort(); // assumes other fields are also retrieved otherwise inefficient
|
||||||
return _ar[_p[_cnt-1]];
|
return _ar[_p[_cnt-1]];
|
||||||
// return _as[_cnt-1];
|
|
||||||
}
|
}
|
||||||
return NAN;
|
return NAN;
|
||||||
}
|
}
|
||||||
@ -87,7 +86,6 @@ float RunningMedian::getLowest()
|
|||||||
{
|
{
|
||||||
if (_sorted == false) sort();
|
if (_sorted == false) sort();
|
||||||
return _ar[_p[0]];
|
return _ar[_p[0]];
|
||||||
// return _as[0];
|
|
||||||
}
|
}
|
||||||
return NAN;
|
return NAN;
|
||||||
}
|
}
|
||||||
@ -110,9 +108,11 @@ float RunningMedian::getAverage(uint8_t nMedians)
|
|||||||
if (_cnt < nMedians) nMedians = _cnt; // when filling the array for first time
|
if (_cnt < nMedians) nMedians = _cnt; // when filling the array for first time
|
||||||
uint8_t start = ((_cnt - nMedians)/2);
|
uint8_t start = ((_cnt - nMedians)/2);
|
||||||
uint8_t stop = start + nMedians;
|
uint8_t stop = start + nMedians;
|
||||||
|
|
||||||
if (_sorted == false) sort();
|
if (_sorted == false) sort();
|
||||||
|
|
||||||
float sum = 0;
|
float sum = 0;
|
||||||
for (uint8_t i = start; i < stop; i++) sum += _ar[_p[i]]; // _as[i];
|
for (uint8_t i = start; i < stop; i++) sum += _ar[_p[i]];
|
||||||
return sum / nMedians;
|
return sum / nMedians;
|
||||||
}
|
}
|
||||||
return NAN;
|
return NAN;
|
||||||
@ -125,15 +125,7 @@ uint8_t RunningMedian::getCount() { return _cnt; };
|
|||||||
|
|
||||||
void RunningMedian::sort()
|
void RunningMedian::sort()
|
||||||
{
|
{
|
||||||
// Serial.print("befor:\t");
|
// bubble sort with flag
|
||||||
// for (uint8_t i=0; i< _cnt; i++)
|
|
||||||
// {
|
|
||||||
// Serial.print(_ar[_p[i]]);
|
|
||||||
// Serial.print('\t');
|
|
||||||
// }
|
|
||||||
// Serial.println();
|
|
||||||
|
|
||||||
// sort all
|
|
||||||
for (uint8_t i=0; i< _cnt-1; i++)
|
for (uint8_t i=0; i< _cnt-1; i++)
|
||||||
{
|
{
|
||||||
bool flag = true;
|
bool flag = true;
|
||||||
@ -150,52 +142,7 @@ void RunningMedian::sort()
|
|||||||
if (flag) break;
|
if (flag) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// for (uint8_t i=0; i< _cnt-1; i++)
|
|
||||||
// {
|
|
||||||
// uint8_t m = i;
|
|
||||||
// for (uint8_t j=i+1; j< _cnt; j++)
|
|
||||||
// {
|
|
||||||
// if (_ar[_p[j]] < _ar[_p[m]]) m = j;
|
|
||||||
// }
|
|
||||||
// if ( m != i )
|
|
||||||
// {
|
|
||||||
// uint8_t t = _p[i];
|
|
||||||
// _p[i] = _p[m];
|
|
||||||
// _p[m] = t;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Serial.print("after:\t");
|
|
||||||
// for (uint8_t i=0; i< _cnt; i++)
|
|
||||||
// {
|
|
||||||
// Serial.print(_ar[_p[i]]);
|
|
||||||
// Serial.print('\t');
|
|
||||||
// }
|
|
||||||
// Serial.println();
|
|
||||||
_sorted = true;
|
_sorted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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)
|
|
||||||
// {
|
|
||||||
// float t = _as[m];
|
|
||||||
// _as[m] = _as[i];
|
|
||||||
// _as[i] = t;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// _sorted = true;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// END OF FILE
|
// END OF FILE
|
@ -32,8 +32,9 @@
|
|||||||
|
|
||||||
// should at least be 5 to be practical
|
// should at least be 5 to be practical
|
||||||
// odd size results in a 'real' middle element.
|
// odd size results in a 'real' middle element.
|
||||||
|
// even size takes the lower of the two middle elements (TODO)
|
||||||
#define MEDIAN_MIN_SIZE 1
|
#define MEDIAN_MIN_SIZE 1
|
||||||
#define MEDIAN_MAX_SIZE 19 // can be adjusted if needed
|
#define MEDIAN_MAX_SIZE 19 // adjust if needed
|
||||||
|
|
||||||
|
|
||||||
class RunningMedian
|
class RunningMedian
|
||||||
@ -64,11 +65,9 @@ protected:
|
|||||||
|
|
||||||
#ifdef RUNNING_MEDIAN_USE_MALLOC
|
#ifdef RUNNING_MEDIAN_USE_MALLOC
|
||||||
float * _ar;
|
float * _ar;
|
||||||
// float * _as;
|
|
||||||
uint8_t * _p;
|
uint8_t * _p;
|
||||||
#else
|
#else
|
||||||
float _ar[MEDIAN_MAX_SIZE];
|
float _ar[MEDIAN_MAX_SIZE];
|
||||||
// float _as[MEDIAN_MAX_SIZE];
|
|
||||||
uint8_t _p[MEDIAN_MAX_SIZE];
|
uint8_t _p[MEDIAN_MAX_SIZE];
|
||||||
#endif
|
#endif
|
||||||
void sort();
|
void sort();
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
#include "RunningMedian.h"
|
#include "RunningMedian.h"
|
||||||
|
|
||||||
RunningMedian samples = RunningMedian(15);
|
RunningMedian samples = RunningMedian(7);
|
||||||
|
|
||||||
long count = 0;
|
long count = 0;
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ void loop()
|
|||||||
|
|
||||||
void test1()
|
void test1()
|
||||||
{
|
{
|
||||||
if (count % 20 == 0) Serial.println(F("\nmsec \tAnR \tSize \tCnt \tLow \tAvg \tAvg(3) \tMed \tHigh"));
|
if (count % 20 == 0) Serial.println(F("\nmsec \tAnR \tSize \tCnt \tLow \tAvg \tAvg(7) \tAvg(3) \tMed \tHigh"));
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
long x = analogRead(A0);
|
long x = analogRead(A0);
|
||||||
@ -39,6 +39,7 @@ void test1()
|
|||||||
float l = samples.getLowest();
|
float l = samples.getLowest();
|
||||||
float m = samples.getMedian();
|
float m = samples.getMedian();
|
||||||
float a = samples.getAverage();
|
float a = samples.getAverage();
|
||||||
|
float a7 = samples.getAverage(7);
|
||||||
float a3 = samples.getAverage(3);
|
float a3 = samples.getAverage(3);
|
||||||
float h = samples.getHighest();
|
float h = samples.getHighest();
|
||||||
int s = samples.getSize();
|
int s = samples.getSize();
|
||||||
@ -56,6 +57,8 @@ void test1()
|
|||||||
Serial.print('\t');
|
Serial.print('\t');
|
||||||
Serial.print(a, 2);
|
Serial.print(a, 2);
|
||||||
Serial.print('\t');
|
Serial.print('\t');
|
||||||
|
Serial.print(a7, 2);
|
||||||
|
Serial.print('\t');
|
||||||
Serial.print(a3, 2);
|
Serial.print(a3, 2);
|
||||||
Serial.print('\t');
|
Serial.print('\t');
|
||||||
Serial.print(m);
|
Serial.print(m);
|
||||||
@ -64,3 +67,4 @@ void test1()
|
|||||||
delay(100);
|
delay(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user