3-phase PV router
Loading...
Searching...
No Matches
movingAvg.h
Go to the documentation of this file.
1
12#ifndef MOVINGAVG_H
13#define MOVINGAVG_H
14
15#include <Arduino.h>
16
17#include "type_traits.hpp"
18
39template< typename T, uint8_t DURATION_IN_MINUTES = 10, uint8_t VALUES_PER_MINUTE = 10 >
41{
42public:
47 void clear()
48 {
49 _idx = 0;
50
52 {
53 _sum = 0.0F;
54 }
55 else
56 {
57 _sum = 0;
58 }
59
60 uint8_t i{ DURATION_IN_MINUTES };
61 do {
62 --i;
64 {
65 _ar[i] = 0.0F;
66 }
67 else
68 {
69 _ar[i] = 0;
70 }
71 } while (i);
72
73 _clear_sub();
74 }
75
81 void addValue(const T& _value)
82 {
84 _sub_ar[_sub_idx] = _value;
85 _sub_sum += _value;
86 ++_sub_idx;
87
88 if (_sub_idx == VALUES_PER_MINUTE)
89 {
90 _sub_idx = 0; // faster than %
92 }
93 }
94
95 void fillValue(const T& _value)
96 {
97 _idx = 0;
98 _sum = DURATION_IN_MINUTES * _value;
99
100 uint8_t i{ DURATION_IN_MINUTES };
101 do
102 {
103 _ar[--i] = _value;
104 } while (i);
105 }
106
115 auto getAverage() const
116 {
117 if constexpr (DURATION_IN_MINUTES == 1)
118 return _getAverage();
119 else if constexpr (DURATION_IN_MINUTES == 2)
120 return _sum >> 1;
121 else if constexpr (DURATION_IN_MINUTES == 4)
122 return _sum >> 2;
123 else if constexpr (DURATION_IN_MINUTES == 8)
124 return _sum >> 3;
125 else if constexpr (DURATION_IN_MINUTES == 16)
126 return _sum >> 4;
127 else if constexpr (DURATION_IN_MINUTES == 32)
128 return _sum >> 5;
129 else
130 return _sum * invN;
131 }
132
133 auto getElement(uint8_t idx) const
134 {
135 if (idx >= DURATION_IN_MINUTES)
136 {
137 if constexpr (is_floating_point< T >::value)
138 return 0.0F;
139 else
140 return (T)0;
141 }
142
143 return _ar[idx];
144 }
145
146 [[nodiscard]] constexpr uint8_t getSize() const
147 {
148 return DURATION_IN_MINUTES;
149 }
150
151private:
153 {
154 _sub_idx = 0;
155
156 if constexpr (is_floating_point< T >::value)
157 _sub_sum = 0.0F;
158 else
159 _sub_sum = 0;
160
161 uint8_t i{ VALUES_PER_MINUTE };
162 do {
163 --i;
164 if constexpr (is_floating_point< T >::value)
165 _sub_ar[i] = 0.0F;
166 else
167 _sub_ar[i] = 0;
168 } while (i);
169 }
170
171 void _addValue(const T& _value)
172 {
173 _sum -= _ar[_idx];
174 _ar[_idx] = _value;
175 _sum += _value;
176 ++_idx;
177
178 if (_idx == DURATION_IN_MINUTES)
179 {
180 _idx = 0; // faster than %
181 }
182 }
183
184 auto _getAverage() const
185 {
186 return _sub_sum * invD;
187 }
188
189private:
190 uint8_t _idx{ 0 };
191 uint8_t _sub_idx{ 0 };
192 typename conditional< is_floating_point< T >::value, T, int32_t >::type _sum{ 0 };
193 typename conditional< is_floating_point< T >::value, T, int32_t >::type _sub_sum{ 0 };
194
195 T _sub_ar[VALUES_PER_MINUTE]{};
196 T _ar[DURATION_IN_MINUTES]{};
197
198 static constexpr float invD{ 1.0 / VALUES_PER_MINUTE };
199 static constexpr float invN{ 1.0 / DURATION_IN_MINUTES };
200};
201
202#endif
Template class for implementing a sliding average.
Definition: movingAvg.h:41
static constexpr float invN
Definition: movingAvg.h:199
conditional< is_floating_point< T >::value, T, int32_t >::type _sum
Definition: movingAvg.h:192
auto getAverage() const
Get the sliding average.
Definition: movingAvg.h:115
constexpr uint8_t getSize() const
Definition: movingAvg.h:146
T _ar[DURATION_IN_MINUTES]
Definition: movingAvg.h:196
void _clear_sub()
Definition: movingAvg.h:152
void _addValue(const T &_value)
Definition: movingAvg.h:171
void addValue(const T &_value)
Add a value.
Definition: movingAvg.h:81
void fillValue(const T &_value)
Definition: movingAvg.h:95
uint8_t _sub_idx
Definition: movingAvg.h:191
uint8_t _idx
Definition: movingAvg.h:190
conditional< is_floating_point< T >::value, T, int32_t >::type _sub_sum
Definition: movingAvg.h:193
void clear()
Reset everything.
Definition: movingAvg.h:47
auto _getAverage() const
Definition: movingAvg.h:184
static constexpr float invD
Definition: movingAvg.h:198
T _sub_ar[VALUES_PER_MINUTE]
Definition: movingAvg.h:195
auto getElement(uint8_t idx) const
Definition: movingAvg.h:133
uint8_t i
Definition: test_main.cpp:94
Some useful but missing stl functions templates.