#include <AH/Filters/EMA.hpp>
Exponential moving average filter.
Fast integer EMA implementation where the weight factor is a power of two.
Difference equation: \( y[n] = \alpha·x[n]+(1-\alpha)·y[n-1] \) where \( \alpha = \left(\frac{1}{2}\right)^{K} \), \( x \) is the input sequence, and \( y \) is the output sequence.
An in-depth explanation of the EMA filter
| K | The amount of bits to shift by. This determines the location of the pole in the EMA transfer function, and therefore the cut-off frequency. The higher this number, the more filtering takes place. The pole location is \( 1 - 2^{-K} \). |
| input_t | The integer type to use for the input and output of the filter. Can be signed or unsigned. |
| state_t | The unsigned integer type to use for the internal state of the filter. A fixed-point representation with \( K \) fractional bits is used, so this type should be at least \( M + K \) bits wide, where \( M \) is the maximum number of bits of the input. |
Some examples of different combinations of template parameters:
analogRead: analogRead returns an integer between 0 and 1023, which can be represented using 10 bits, so \( M = 10 \). If input_t and output_t are both uint16_t, the maximum shift factor K is \( 16 - M = 6 \). If state_t is increased to uint32_t, the maximum shift factor K is \( 32 - M = 22 \).input_t is int16_t, and \( M = 16 \). (2¹⁵ = 32768) Let's say the shift factor K is 1, then the minimum width of state_t should be \( M + K = 17 \) bits, so uint32_t would be a sensible choice.
Collaboration diagram for EMA< K, input_t, state_t >:Public Member Functions | |
| EMA (input_t initial=input_t{0}) | |
| Constructor: initialize filter to zero or optional given value. | |
| void | reset (input_t value=input_t(0)) |
| Reset the filter to the given value. | |
| input_t | filter (input_t input) |
| Filter the input: Given \( x[n] \), calculate \( y[n] \). | |
| input_t | operator() (input_t input) |
| Filter the input: Given \( x[n] \), calculate \( y[n] \). | |
Static Public Member Functions | |
| template<class T > | |
| 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 type. | |
Static Public Attributes | |
| static constexpr state_t | max_state = std::numeric_limits<state_t>::max() |
| static constexpr state_t | half_state = max_state / 2 + 1 |
| static constexpr state_t | zero = std::is_unsigned<input_t>::value ? state_t{0} : half_state |
| static constexpr state_t | half = K > 0 ? state_t{1} << (K - 1) : state_t{0} |
Private Attributes | |
| state_t | state |
|
inlinestaticconstexpr |
Verify the input range to make sure it's compatible with the shift factor and the width of the state type.
Examples: