Control Surface  1.1.1
MIDI Control Surface library for Arduino
FilteredAnalog.hpp
Go to the documentation of this file.
1 #pragma once
2 
4 AH_DIAGNOSTIC_WERROR() // Enable errors on warnings
5 
6 #include <AH/Filters/EMA.hpp>
11 #include <AH/Math/MinMaxFix.hpp>
13 
15 
49 template <uint8_t Precision = 10,
50  uint8_t FilterShiftFactor = ANALOG_FILTER_SHIFT_FACTOR,
51  class FilterType = ANALOG_FILTER_TYPE, class AnalogType = analog_t,
52  uint8_t IncRes =
53  min(sizeof(FilterType) * CHAR_BIT - ADC_BITS - FilterShiftFactor,
54  sizeof(AnalogType) * CHAR_BIT - ADC_BITS)>
56  public:
63  FilteredAnalog(pin_t analogPin) : analogPin(analogPin) {}
64 
67  using MappingFunction = AnalogType (*)(AnalogType);
68 
86  void map(MappingFunction fn) { mapFn = fn; }
87 
95  void invert() {
96  constexpr AnalogType maxval = (1UL << (ADC_BITS + IncRes)) - 1;
97  map([](AnalogType val) -> AnalogType { return maxval - val; });
98  }
99 
109  bool update() {
110  AnalogType input = getRawValue(); // read the raw analog input value
111  input = filter.filter(input); // apply a low-pass EMA filter
112  if (mapFn) // If a mapping function is specified,
113  input = mapFn(input); // apply it
114  return hysteresis.update(input); // apply hysteresis, and return true
115  // if the value changed since last time
116  }
117 
128  AnalogType getValue() const { return hysteresis.getValue(); }
129 
137  float getFloatValue() const {
138  return getValue() * (1.0f / (ldexpf(1.0f, Precision) - 1.0f));
139  }
140 
145  AnalogType getRawValue() const {
146  return increaseBitDepth<ADC_BITS + IncRes, ADC_BITS, AnalogType,
147  AnalogType>(ExtIO::analogRead(analogPin));
148  }
149 
157  static void setupADC() {
158 #if HAS_ANALOG_READ_RESOLUTION
159  analogReadResolution(ADC_BITS);
160 #endif
161  }
162 
163  private:
165 
166  MappingFunction mapFn = nullptr;
167 
168  static_assert(
169  ADC_BITS + IncRes + FilterShiftFactor <= sizeof(FilterType) * CHAR_BIT,
170  "Error: FilterType is not wide enough to hold the maximum value");
171  static_assert(
172  ADC_BITS + IncRes <= sizeof(AnalogType) * CHAR_BIT,
173  "Error: AnalogType is not wide enough to hold the maximum value");
174  static_assert(
175  Precision <= ADC_BITS + IncRes,
176  "Error: Precision is larger than the increased ADC precision");
177 
179  Hysteresis<ADC_BITS + IncRes - Precision, AnalogType, AnalogType>
181 };
182 
184 
AH::FilteredAnalog::map
void map(MappingFunction fn)
Specify a mapping function that is applied to the raw analog value before filtering.
Definition: FilteredAnalog.hpp:86
AH::FilteredAnalog::getValue
AnalogType getValue() const
Get the filtered value of the analog input (with the mapping function applied).
Definition: FilteredAnalog.hpp:128
AH::FilteredAnalog::getRawValue
AnalogType getRawValue() const
Read the raw value of the analog input any filtering or mapping applied, but with its bit depth incre...
Definition: FilteredAnalog.hpp:145
AH::FilteredAnalog::filter
EMA< FilterShiftFactor, FilterType > filter
Definition: FilteredAnalog.hpp:170
Warnings.hpp
Hysteresis.hpp
AH::increaseBitDepth
T_out increaseBitDepth(T_in in)
Increase the bit depth of the given value from Bits_in bits wide to Bits_out bits wide,...
Definition: IncreaseBitDepth.hpp:68
AH::FilteredAnalog::hysteresis
Hysteresis< ADC_BITS+IncRes - Precision, AnalogType, AnalogType > hysteresis
Definition: FilteredAnalog.hpp:180
AH::FilteredAnalog< ContinuousCCSender ::precision()>::MappingFunction
analog_t(*)(analog_t) MappingFunction
A function pointer to a mapping function to map analog values.
Definition: FilteredAnalog.hpp:67
AH::pin_t
uint16_t pin_t
The type for Arduino pins (and ExtendedIOElement pins).
Definition: Hardware-Types.hpp:17
AH::ANALOG_FILTER_SHIFT_FACTOR
constexpr uint8_t ANALOG_FILTER_SHIFT_FACTOR
The factor for the analog filter: Difference equation: where .
Definition: AH/Settings/Settings.hpp:64
SettingsWrapper.hpp
ExtendedInputOutput.hpp
AH::min
constexpr auto min(const T &a, const U &b) -> decltype(b< a ? b :a)
Return the smaller of two numbers/objects.
Definition: MinMaxFix.hpp:15
IncreaseBitDepth.hpp
AH_DIAGNOSTIC_POP
#define AH_DIAGNOSTIC_POP()
Definition: Warnings.hpp:17
AH::FilteredAnalog::FilteredAnalog
FilteredAnalog(pin_t analogPin)
Construct a new FilteredAnalog object.
Definition: FilteredAnalog.hpp:63
AH::FilteredAnalog
A class that reads and filters an analog input.
Definition: FilteredAnalog.hpp:55
AH::ADC_BITS
constexpr uint8_t ADC_BITS
The bit depth to use for the ADC (Analog to Digital Converter).
Definition: AH/Settings/Settings.hpp:53
AH::ExtIO::analogRead
analog_t analogRead(pin_t pin)
An ExtIO version of the Arduino function.
Definition: ExtendedInputOutput.cpp:90
EMA< FilterShiftFactor, FilterType >
Hysteresis
A class for applying hysteresis to a given input.
Definition: Hysteresis.hpp:36
AH::analog_t
uint16_t analog_t
The type returned from analogRead and similar functions.
Definition: Hardware-Types.hpp:15
AH::ANALOG_FILTER_TYPE
uint16_t ANALOG_FILTER_TYPE
The unsigned integer type to use for analog inputs during filtering.
Definition: AH/Settings/Settings.hpp:71
AH::FilteredAnalog::invert
void invert()
Invert the analog value.
Definition: FilteredAnalog.hpp:95
AH::FilteredAnalog::setupADC
static void setupADC()
Select the configured ADC resolution.
Definition: FilteredAnalog.hpp:157
AH_DIAGNOSTIC_WERROR
#define AH_DIAGNOSTIC_WERROR()
Definition: Warnings.hpp:16
BEGIN_AH_NAMESPACE
#define BEGIN_AH_NAMESPACE
Definition: AH/Settings/NamespaceSettings.hpp:9
END_AH_NAMESPACE
#define END_AH_NAMESPACE
Definition: AH/Settings/NamespaceSettings.hpp:10
MinMaxFix.hpp
AH::FilteredAnalog::analogPin
const pin_t analogPin
Definition: FilteredAnalog.hpp:164
Hardware-Types.hpp
AH::FilteredAnalog::getFloatValue
float getFloatValue() const
Get the filtered value of the analog input with the mapping function applied as a floating point numb...
Definition: FilteredAnalog.hpp:137
AH::FilteredAnalog::update
bool update()
Read the analog input value, apply the mapping function, and update the average.
Definition: FilteredAnalog.hpp:109