This is an old version of the documentation. View the latest version here.
Control Surface  1.0.0
MIDI Control Surface library for Arduino
FilteredAnalog.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <Def/Def.hpp>
5 #include <Helpers/EMA.hpp>
6 #include <Helpers/Hysteresis.hpp>
8 #include <Helpers/MinMaxFix.hpp>
10 
12 
41 template <uint8_t Precision = 10,
42  uint8_t FilterShiftFactor = ANALOG_FILTER_SHIFT_FACTOR,
43  class FilterType = ANALOG_FILTER_TYPE,
44  uint8_t Upsample =
45  min(sizeof(FilterType) * CHAR_BIT - ADC_BITS - FilterShiftFactor,
46  sizeof(analog_t) * CHAR_BIT - ADC_BITS)>
48  public:
56 
74  void map(MappingFunction fn) { mapFn = fn; }
75 
83  void invert() {
84  constexpr analog_t maxval = (1 << (ADC_BITS + Upsample)) - 1;
85  map([](analog_t val) -> analog_t { return maxval - val; });
86  }
87 
97  bool update() {
98  analog_t input = getRawValue(); // read the raw analog input value
99  input = filter.filter(input); // apply a low-pass EMA filter
100  if (mapFn) // If a mapping function is specified,
101  input = mapFn(input); // apply it
102  return hysteresis.update(input); // apply hysteresis, and return true if
103  // the value changed since last time
104  }
105 
113  analog_t getValue() const { return hysteresis.getValue(); }
114 
122  float getFloatValue() const {
123  return getValue() * (1.0f / (ldexpf(1.0f, Precision) - 1.0f));
124  }
125 
131  return increaseBitDepth<ADC_BITS + Upsample, ADC_BITS, analog_t,
133  }
134 
135  static void setupADC() {
136 #if HAS_ANALOG_READ_RESOLUTION
137  analogReadResolution(ADC_BITS);
138 #endif
139  }
140 
141  private:
143 
145 
146  static_assert(
147  ADC_BITS + Upsample + FilterShiftFactor <=
148  sizeof(FilterType) * CHAR_BIT,
149  "Error: FilterType is not wide enough to hold the maximum value");
150  static_assert(
151  ADC_BITS + Upsample <= sizeof(analog_t) * CHAR_BIT,
152  "Error: analog_t is not wide enough to hold the maximum value");
153  static_assert(
154  Precision <= ADC_BITS + Upsample,
155  "Error: Precision is larger than the upsampled ADC precision");
156 
158  Hysteresis<ADC_BITS + Upsample - Precision, analog_t, analog_t> hysteresis;
159 };
160 
ANALOG_FILTER_TYPE
uint16_t ANALOG_FILTER_TYPE
The unsigned integer type to use for analog inputs during filtering.
Definition: Settings.hpp:69
ADC_BITS
constexpr uint8_t ADC_BITS
The bit depth to use for the ADC (Analog to Digital Converter).
Definition: Settings.hpp:51
Hysteresis.hpp
FilteredAnalog
A class that reads and filters an analog input.
Definition: FilteredAnalog.hpp:47
pin_t
uint16_t pin_t
The type for Arduino pins (and ExtendedIOElement pins).
Definition: Def.hpp:17
FilteredAnalog::hysteresis
Hysteresis< ADC_BITS+Upsample - Precision, analog_t, analog_t > hysteresis
Definition: FilteredAnalog.hpp:158
Def.hpp
ExtendedInputOutput.hpp
FilteredAnalog::filter
EMA< FilterShiftFactor, FilterType > filter
Definition: FilteredAnalog.hpp:149
IncreaseBitDepth.hpp
FilteredAnalog::getRawValue
analog_t getRawValue() const
Read the raw value of the analog input any filtering or mapping applied, but with its bit depth incre...
Definition: FilteredAnalog.hpp:130
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:122
FilteredAnalog::update
bool update()
Read the analog input value, apply the mapping function, and update the average.
Definition: FilteredAnalog.hpp:97
BEGIN_CS_NAMESPACE
#define BEGIN_CS_NAMESPACE
Definition: NamespaceSettings.hpp:9
analog_t
uint16_t analog_t
The type returned from analogRead and similar functions.
Definition: Def.hpp:15
EMA< FilterShiftFactor, FilterType >
Hysteresis
A class for applying hysteresis to a given input.
Definition: Hysteresis.hpp:33
FilteredAnalog::getValue
analog_t getValue() const
Get the filtered value of the analog input with the mapping function applied.
Definition: FilteredAnalog.hpp:113
EMA.hpp
ANALOG_FILTER_SHIFT_FACTOR
constexpr uint8_t ANALOG_FILTER_SHIFT_FACTOR
The factor for the analog filter: Difference equation: where .
Definition: Settings.hpp:62
EMA::filter
uint_t filter(uint_t input)
Filter the input: Given , calculate .
Definition: EMA.hpp:48
END_CS_NAMESPACE
#define END_CS_NAMESPACE
Definition: NamespaceSettings.hpp:10
FilteredAnalog::mapFn
MappingFunction mapFn
Definition: FilteredAnalog.hpp:144
FilteredAnalog::analogPin
const pin_t analogPin
Definition: FilteredAnalog.hpp:142
FilteredAnalog::map
void map(MappingFunction fn)
Specify a mapping function that is applied to the raw analog value before filtering.
Definition: FilteredAnalog.hpp:74
FilteredAnalog::invert
void invert()
Invert the analog value.
Definition: FilteredAnalog.hpp:83
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:60
Hysteresis::update
bool update(T_in inputLevel)
Update the hysteresis output with a new input value.
Definition: Hysteresis.hpp:45
MinMaxFix.hpp
SettingsWrapper.hpp
Hysteresis::getValue
T_out getValue() const
Get the current output level.
Definition: Hysteresis.hpp:61
MappingFunction
analog_t(*)(analog_t) MappingFunction
A function pointer to a mapping function to map analog values.
Definition: Def.hpp:28
min
constexpr auto min(const T &a, const U &b) -> decltype(b< a ? b :a)
Definition: MinMaxFix.hpp:11
FilteredAnalog::FilteredAnalog
FilteredAnalog(pin_t analogPin)
Construct a new FilteredAnalog object.
Definition: FilteredAnalog.hpp:55
ExtIO::analogRead
analog_t analogRead(pin_t pin)
An ExtIO version of the Arduino function.
Definition: ExtendedInputOutput.cpp:84
FilteredAnalog::setupADC
static void setupADC()
Definition: FilteredAnalog.hpp:135