Skip to content

Commit ff52d49

Browse files
committed
+ version 0.1.06
+ dynamic internal buffers + replace sorted buffer with "indirection buffer" + bubble sort + flag (faster)
1 parent 28b1b43 commit ff52d49

File tree

3 files changed

+21
-71
lines changed

3 files changed

+21
-71
lines changed

libraries/RunningMedian/RunningMedian.cpp

Lines changed: 12 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
// 0.1.03 - 2013-09-30 added _sorted flag, minor refactor
1212
// 0.1.04 - 2013-10-17 added getAverage(uint8_t) - kudo's to Sembazuru
1313
// 0.1.05 - 2013-10-18 fixed bug in sort; removes default constructor; dynamic memory
14-
// 0.1.06 - 2013-10-19 faster sort? more dyn test.
14+
// 0.1.06 - 2013-10-19 faster sort, dynamic arrays, replaced sorted float array with indirection array
1515
//
1616
// Released to the public domain
1717
//
@@ -21,10 +21,10 @@
2121
RunningMedian::RunningMedian(uint8_t size)
2222
{
2323
_size = constrain(size, MEDIAN_MIN_SIZE, MEDIAN_MAX_SIZE);
24-
24+
2525
#ifdef RUNNING_MEDIAN_USE_MALLOC
2626
_ar = (float *) malloc(_size * sizeof(float));
27-
_p = (uint8_t *) malloc(size * sizeof(uint8_t));
27+
_p = (uint8_t *) malloc(_size * sizeof(uint8_t));
2828
#endif
2929

3030
clear();
@@ -45,15 +45,16 @@ void RunningMedian::clear()
4545
_idx = 0;
4646
_sorted = false;
4747

48-
// for (uint8_t i=0; i< _size; i++) _p[i] = i;
48+
for (uint8_t i=0; i< _size; i++) _p[i] = i;
4949
}
5050

5151
// adds a new value to the data-set
5252
// or overwrites the oldest if full.
5353
void RunningMedian::add(float value)
5454
{
55-
_ar[_idx++] = value;
55+
_idx++;
5656
if (_idx >= _size) _idx = 0; // wrap around
57+
_ar[_idx] = value;
5758
if (_cnt < _size) _cnt++;
5859
_sorted = false;
5960
}
@@ -64,7 +65,6 @@ float RunningMedian::getMedian()
6465
{
6566
if (_sorted == false) sort();
6667
return _ar[_p[_cnt/2]];
67-
// return _as[_cnt/2];
6868
}
6969
return NAN;
7070
}
@@ -74,9 +74,8 @@ float RunningMedian::getHighest()
7474
{
7575
if (_cnt > 0)
7676
{
77-
if (_sorted == false) sort();
77+
if (_sorted == false) sort(); // assumes other fields are also retrieved otherwise inefficient
7878
return _ar[_p[_cnt-1]];
79-
// return _as[_cnt-1];
8079
}
8180
return NAN;
8281
}
@@ -87,7 +86,6 @@ float RunningMedian::getLowest()
8786
{
8887
if (_sorted == false) sort();
8988
return _ar[_p[0]];
90-
// return _as[0];
9189
}
9290
return NAN;
9391
}
@@ -110,9 +108,11 @@ float RunningMedian::getAverage(uint8_t nMedians)
110108
if (_cnt < nMedians) nMedians = _cnt; // when filling the array for first time
111109
uint8_t start = ((_cnt - nMedians)/2);
112110
uint8_t stop = start + nMedians;
111+
113112
if (_sorted == false) sort();
113+
114114
float sum = 0;
115-
for (uint8_t i = start; i < stop; i++) sum += _ar[_p[i]]; // _as[i];
115+
for (uint8_t i = start; i < stop; i++) sum += _ar[_p[i]];
116116
return sum / nMedians;
117117
}
118118
return NAN;
@@ -125,15 +125,7 @@ uint8_t RunningMedian::getCount() { return _cnt; };
125125

126126
void RunningMedian::sort()
127127
{
128-
// Serial.print("befor:\t");
129-
// for (uint8_t i=0; i< _cnt; i++)
130-
// {
131-
// Serial.print(_ar[_p[i]]);
132-
// Serial.print('\t');
133-
// }
134-
// Serial.println();
135-
136-
// sort all
128+
// bubble sort with flag
137129
for (uint8_t i=0; i< _cnt-1; i++)
138130
{
139131
bool flag = true;
@@ -149,53 +141,8 @@ void RunningMedian::sort()
149141
}
150142
if (flag) break;
151143
}
152-
153-
// for (uint8_t i=0; i< _cnt-1; i++)
154-
// {
155-
// uint8_t m = i;
156-
// for (uint8_t j=i+1; j< _cnt; j++)
157-
// {
158-
// if (_ar[_p[j]] < _ar[_p[m]]) m = j;
159-
// }
160-
// if ( m != i )
161-
// {
162-
// uint8_t t = _p[i];
163-
// _p[i] = _p[m];
164-
// _p[m] = t;
165-
// }
166-
// }
167-
168-
// Serial.print("after:\t");
169-
// for (uint8_t i=0; i< _cnt; i++)
170-
// {
171-
// Serial.print(_ar[_p[i]]);
172-
// Serial.print('\t');
173-
// }
174-
// Serial.println();
144+
175145
_sorted = true;
176146
}
177147

178-
// void RunningMedian::sort()
179-
// {
180-
// // copy
181-
// for (uint8_t i=0; i< _cnt; i++) _as[i] = _ar[i];
182-
183-
// // sort all
184-
// for (uint8_t i=0; i< _cnt-1; i++)
185-
// {
186-
// uint8_t m = i;
187-
// for (uint8_t j=i+1; j< _cnt; j++)
188-
// {
189-
// if (_as[j] < _as[m]) m = j;
190-
// }
191-
// if (m != i)
192-
// {
193-
// float t = _as[m];
194-
// _as[m] = _as[i];
195-
// _as[i] = t;
196-
// }
197-
// }
198-
// _sorted = true;
199-
// }
200-
201148
// END OF FILE

libraries/RunningMedian/RunningMedian.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@
3232

3333
// should at least be 5 to be practical
3434
// odd size results in a 'real' middle element.
35+
// even size takes the lower of the two middle elements (TODO)
3536
#define MEDIAN_MIN_SIZE 1
36-
#define MEDIAN_MAX_SIZE 19 // can be adjusted if needed
37+
#define MEDIAN_MAX_SIZE 19 // adjust if needed
3738

3839

3940
class RunningMedian
@@ -64,11 +65,9 @@ class RunningMedian
6465

6566
#ifdef RUNNING_MEDIAN_USE_MALLOC
6667
float * _ar;
67-
// float * _as;
6868
uint8_t * _p;
6969
#else
7070
float _ar[MEDIAN_MAX_SIZE];
71-
// float _as[MEDIAN_MAX_SIZE];
7271
uint8_t _p[MEDIAN_MAX_SIZE];
7372
#endif
7473
void sort();

libraries/RunningMedian/examples/RunningMedian2/RunningMedian2.ino

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
#include "RunningMedian.h"
1313

14-
RunningMedian samples = RunningMedian(15);
14+
RunningMedian samples = RunningMedian(7);
1515

1616
long count = 0;
1717

@@ -29,16 +29,17 @@ void loop()
2929

3030
void test1()
3131
{
32-
if (count % 20 == 0) Serial.println(F("\nmsec \tAnR \tSize \tCnt \tLow \tAvg \tAvg(3) \tMed \tHigh"));
32+
if (count % 20 == 0) Serial.println(F("\nmsec \tAnR \tSize \tCnt \tLow \tAvg \tAvg(7) \tAvg(3) \tMed \tHigh"));
3333
count++;
34-
34+
3535
long x = analogRead(A0);
3636

3737
samples.add(x);
3838

3939
float l = samples.getLowest();
4040
float m = samples.getMedian();
4141
float a = samples.getAverage();
42+
float a7 = samples.getAverage(7);
4243
float a3 = samples.getAverage(3);
4344
float h = samples.getHighest();
4445
int s = samples.getSize();
@@ -56,6 +57,8 @@ void test1()
5657
Serial.print('\t');
5758
Serial.print(a, 2);
5859
Serial.print('\t');
60+
Serial.print(a7, 2);
61+
Serial.print('\t');
5962
Serial.print(a3, 2);
6063
Serial.print('\t');
6164
Serial.print(m);
@@ -64,3 +67,4 @@ void test1()
6467
delay(100);
6568
}
6669

70+

0 commit comments

Comments
 (0)