-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathmovingAverage.h
111 lines (84 loc) · 2.23 KB
/
movingAverage.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/*
* movingAverage.h
*
* Created on: 13.11.2014
* Author: user
*/
#ifndef MOVINGAVERAGE_H_
#define MOVINGAVERAGE_H_
// A linear Moving Average Class
//
// the size of the buffer is passed in the constructor
// datatype is set by a template parameter
//
// Values are weightened by index*(255-(255/size))
//
// works only for uint8_t and uint16_t!
template <typename type>
class MovingAverageLinear {
public:
// construct an object with the given buffer size
MovingAverageLinear(uint8_t size);
~MovingAverageLinear();
// add another value to the buffer
void add(type value);
// calculate current average of all elements in buffer
type getAverage();
// delete all elements from buffer but set a value that is returned as average
void clear();
// returns the number of valid elements in the buffer
uint8_t getFillCount() { return fillCount;}
// individual access to buffer elements
type operator[](uint8_t index) {return values[index];}
private:
bool needUpdate;
type average;
type* values;
uint8_t size;
uint8_t fillCount;
uint8_t linearDecrease;
};
template <typename type>
MovingAverageLinear<type>::MovingAverageLinear(uint8_t size) {
values = new type[size];
this->size = size;
clear();
linearDecrease = 255/(size);
}
template <typename type>
MovingAverageLinear<type>::~MovingAverageLinear() {
if (values != 0) delete values;
}
template <typename type>
void MovingAverageLinear<type>::clear() {
fillCount = 0;
}
template <typename type>
void MovingAverageLinear<type>::add(type value) {
// shift all one back
for (uint8_t index=fillCount; index>=1; index--) {
values[index] = values[index-1];
}
// add current value at front
values[0] = value;
// update status
if (fillCount<size) fillCount++;
needUpdate = true;
}
template <typename type>
type MovingAverageLinear<type>::getAverage() {
// calculate new average if needed
if (needUpdate && fillCount) {
uint32_t tmpVal = 0;
uint16_t tmpWeight = 0;
for (uint8_t index=0; index<fillCount; index++) {
tmpVal += (uint32_t)values[index]*(255-(index*linearDecrease));
tmpWeight += (255-(index*linearDecrease));
}
average = tmpVal/tmpWeight;
needUpdate = false;
}
// return current average
return average;
}
#endif /* MOVINGAVERAGE_H_ */