Control Surface main
MIDI Control Surface library for Arduino
Loading...
Searching...
No Matches
FilteredAnalog.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <AH/Filters/EMA.hpp>
9#include <AH/STL/type_traits> // std::enable_if, std::is_constructible
10#include <AH/STL/utility> // std::forward
12
14
19template <uint8_t FilterShiftFactor, class FilterType, class AnalogType>
21 constexpr static uint8_t value =
22 min(sizeof(FilterType) * CHAR_BIT - ADC_BITS - FilterShiftFactor,
23 sizeof(AnalogType) * CHAR_BIT - ADC_BITS);
24};
25
31template <class MappingFunction, uint8_t Precision = 10,
37 public:
49 AnalogType initial = 0)
50 : analogPin(analogPin), mapFn(std::forward<MappingFunction>(mapFn)),
52 AnalogType>(initial)) {}
53
63 void reset(AnalogType value = 0) {
65 AnalogType, AnalogType>(value);
66 filter.reset(widevalue);
67 hysteresis.setValue(widevalue);
68 }
69
77 AnalogType widevalue = getRawValue();
78 filter.reset(widevalue);
79 hysteresis.setValue(widevalue);
80 }
81
98 void map(MappingFunction fn) { mapFn = std::forward<MappingFunction>(fn); }
99
107 const MappingFunction &getMappingFunction() const { return mapFn; }
108
118 bool update() {
119 AnalogType input = getRawValue(); // read the raw analog input value
120 input = filter.filter(input); // apply a low-pass EMA filter
121 input = mapFnHelper(input); // apply the mapping function
122 return hysteresis.update(input); // apply hysteresis, and return true
123 // if the value changed since last time
124 }
125
136 AnalogType getValue() const { return hysteresis.getValue(); }
137
145 float getFloatValue() const {
146 return getValue() * (1.0f / (ldexpf(1.0f, Precision) - 1.0f));
147 }
148
154 AnalogType value = ExtIO::analogRead(analogPin);
155#ifdef ESP8266
156 if (value > 1023)
157 value = 1023;
158#endif
160 }
161
165 constexpr static AnalogType getMaxRawValue() {
166 return (1ul << (ADC_BITS + IncRes)) - 1ul;
167 }
168
176 static void setupADC() {
177#if HAS_ANALOG_READ_RESOLUTION
179#endif
180 }
181
182 private:
186 template <typename M = MappingFunction>
187 typename std::enable_if<std::is_constructible<bool, M>::value,
188 AnalogType>::type
190 return bool(mapFn) ? mapFn(input) : input;
191 }
192
197 template <typename M = MappingFunction>
198 typename std::enable_if<!std::is_constructible<bool, M>::value,
199 AnalogType>::type
201 return mapFn(input);
202 }
203
204 private:
207
209
210 static_assert(
212 "Error: FilterType is not wide enough to hold the maximum value");
213 static_assert(
214 ADC_BITS + IncRes <= sizeof(AnalogType) * CHAR_BIT,
215 "Error: AnalogType is not wide enough to hold the maximum value");
216 static_assert(
218 "Error: Precision is larger than the increased ADC precision");
219 static_assert(EMA_t::supports_range(AnalogType(0), getMaxRawValue()),
220 "Error: EMA filter type doesn't support full ADC range");
221
225};
226
260template <uint8_t Precision = 10,
266 : public GenericFilteredAnalog<AnalogType (*)(AnalogType), Precision,
267 FilterShiftFactor, FilterType, AnalogType,
268 IncRes> {
269 public:
282
292
296
304 void invert() {
305 constexpr AnalogType maxval = FilteredAnalog::getMaxRawValue();
306 this->map([](AnalogType val) -> AnalogType { return maxval - val; });
307 }
308};
309
#define END_AH_NAMESPACE
#define BEGIN_AH_NAMESPACE
analog_t(*)(analog_t) MappingFunction
Definition Def.hpp:21
A class that reads and filters an analog input.
FilteredAnalog(pin_t analogPin, AnalogType initial=0)
Construct a new FilteredAnalog object.
FilteredAnalog()
Construct a new FilteredAnalog object.
void invert()
Invert the analog value.
FilteredAnalog base class with generic MappingFunction.
GenericFilteredAnalog(pin_t analogPin, MappingFunction mapFn, AnalogType initial=0)
Construct a new GenericFilteredAnalog object.
void resetToCurrentValue()
Reset the filtered value to the value that's currently being measured at the analog input.
static void setupADC()
Select the configured ADC resolution.
std::enable_if<!std::is_constructible< bool, M >::value, AnalogType >::type mapFnHelper(AnalogType input)
Helper function that applies the mapping function without checking if it's enabled.
void map(MappingFunction fn)
Specify a mapping function/functor that is applied to the analog value after filtering and before app...
AnalogType getRawValue() const
Read the raw value of the analog input without any filtering or mapping applied, but with its bit dep...
void reset(AnalogType value=0)
Reset the filter to the given value.
std::enable_if< std::is_constructible< bool, M >::value, AnalogType >::type mapFnHelper(AnalogType input)
Helper function that applies the mapping function if it's enabled.
AnalogType getValue() const
Get the filtered value of the analog input (with the mapping function applied).
float getFloatValue() const
Get the filtered value of the analog input with the mapping function applied as a floating point numb...
bool update()
Read the analog input value, apply the mapping function, and update the average.
MappingFunction & getMappingFunction()
Get a reference to the mapping function.
Hysteresis< ADC_BITS+IncRes - Precision, AnalogType, AnalogType > hysteresis
const MappingFunction & getMappingFunction() const
Get a reference to the mapping function.
static constexpr AnalogType getMaxRawValue()
Get the maximum value that can be returned from getRawValue.
A class for applying hysteresis to a given input.
T_out increaseBitDepth(T_in in)
Increase the bit depth of the given value from Bits_in bits wide to Bits_out bits wide,...
constexpr uint8_t ANALOG_FILTER_SHIFT_FACTOR
The factor for the analog filter: Difference equation: where .
constexpr uint8_t ADC_BITS
The bit depth to use for the ADC (Analog to Digital Converter).
An array wrapper for easy copying, comparing, and iterating.
Definition Array.hpp:32
Helper to determine how many of the remaining bits of the filter data types can be used to achieve hi...