Arduino Helpers master
Utility library for Arduino
EMA.hpp
Go to the documentation of this file.
1/* ✔ */
2
3#pragma once
4
5#include <stdint.h>
6#include <AH/STL/limits>
7#include <AH/STL/type_traits>
8
10
12
56template <uint8_t K,
57 class input_t = uint_fast16_t,
58 class state_t = typename std::make_unsigned<input_t>::type>
59class EMA {
60 public:
62 EMA(input_t initial = input_t{0}) { reset(initial); }
63
70 void reset(input_t value = input_t(0)) {
71 state_t value_s = static_cast<state_t>(value);
72 state = zero + (value_s << K) - value_s;
73 }
74
82 input_t filter(input_t input) {
83 state += static_cast<state_t>(input);
84 state_t output = (state + half) >> K;
85 output -= zero >> K;
86 state -= output;
87 return static_cast<input_t>(output);
88 }
89
91 input_t operator()(input_t input) {
92 return filter(input);
93 }
94
95 constexpr static state_t
98 zero = std::is_unsigned<input_t>::value ? state_t{0} : half_state,
99 half = K > 0 ? state_t{1} << (K - 1) : state_t{0};
100
101 static_assert(std::is_unsigned<state_t>::value,
102 "state type should be unsigned");
103
105 "state type cannot be narrower than input type");
106
121 template <class T>
122 constexpr static bool supports_range(T min, T max) {
123 using sstate_t = typename std::make_signed<state_t>::type;
124 return min <= max &&
127 (std::is_unsigned<input_t>::value
128 ? state_t(max) <= (max_state >> K)
129 : min >= -static_cast<sstate_t>(max_state >> (K + 1)) - 1 &&
130 max <= static_cast<sstate_t>(max_state >> (K + 1)));
131 }
132
133 private:
134 state_t state;
135};
136
137// -------------------------------------------------------------------------- //
138
153class EMA_f {
154 public:
165 EMA_f(float pole) : alpha(1 - pole) {}
166
174 float filter(float value) {
175 filtered += (value - filtered) * alpha;
176 return filtered;
177 }
178
180 float operator()(float value) { return filter(value); }
181
182 private:
183 float alpha;
184 float filtered = 0;
185};
186
#define END_AH_NAMESPACE
#define BEGIN_AH_NAMESPACE
A class for single-pole infinite impulse response filters or exponential moving average filters.
Definition: EMA.hpp:153
float operator()(float value)
Filter the input: Given , calculate .
Definition: EMA.hpp:180
float filter(float value)
Filter the input: Given , calculate .
Definition: EMA.hpp:174
float alpha
Definition: EMA.hpp:183
EMA_f(float pole)
Create an exponential moving average filter with a pole at the given location.
Definition: EMA.hpp:165
float filtered
Definition: EMA.hpp:184
Exponential moving average filter.
Definition: EMA.hpp:59
static constexpr state_t half
Definition: EMA.hpp:99
void reset(input_t value=input_t(0))
Reset the filter to the given value.
Definition: EMA.hpp:70
static constexpr bool supports_range(T min, T max)
Verify the input range to make sure it's compatible with the shift factor and the width of the state ...
Definition: EMA.hpp:122
state_t state
Definition: EMA.hpp:134
input_t filter(input_t input)
Filter the input: Given , calculate .
Definition: EMA.hpp:82
EMA(input_t initial=input_t{0})
Constructor: initialize filter to zero or optional given value.
Definition: EMA.hpp:62
static constexpr state_t max_state
Definition: EMA.hpp:96
static constexpr state_t half_state
Definition: EMA.hpp:97
input_t operator()(input_t input)
Filter the input: Given , calculate .
Definition: EMA.hpp:91
static constexpr state_t zero
Definition: EMA.hpp:98
constexpr auto min(const T &a, const U &b) -> decltype(b< a ? b :a)
Return the smaller of two numbers/objects.
Definition: MinMaxFix.hpp:12
constexpr auto max(const T &a, const U &b) -> decltype(a< b ? b :a)
Return the larger of two numbers/objects.
Definition: MinMaxFix.hpp:19