Control Surface  1.1.1
MIDI Control Surface library for Arduino
AnalogMultiplex.hpp
Go to the documentation of this file.
1 /* ✔ */
2 
3 #pragma once
4 
6 AH_DIAGNOSTIC_WERROR() // Enable errors on warnings
7 
8 #include "ExtendedInputOutput.hpp"
10 #include <AH/Containers/Array.hpp>
11 #include <stdlib.h>
12 
14 
27 template <uint8_t N>
29  public:
44  AnalogMultiplex(pin_t analogPin, const Array<pin_t, N> &addressPins,
45  pin_t enablePin = NO_PIN)
46  : analogPin(analogPin), addressPins(addressPins), enablePin(enablePin) {
47  }
48 
64  void pinMode(pin_t pin, uint8_t mode) override;
65 
70  void digitalWrite(pin_t, uint8_t) override // LCOV_EXCL_LINE
71  __attribute__((deprecated)) {} // LCOV_EXCL_LINE
72 
79  int digitalRead(pin_t pin) override;
80 
87  analog_t analogRead(pin_t pin) override;
88 
93  void analogWrite(pin_t, analog_t) override // LCOV_EXCL_LINE
94  __attribute__((deprecated)) {} // LCOV_EXCL_LINE
95 
100  void begin() override;
101 
106  void update() override {} // LCOV_EXCL_LINE
107 
108  private:
109  const pin_t analogPin;
110  const Array<pin_t, N> addressPins;
111  const pin_t enablePin;
112 
120  void setMuxAddress(uint8_t address);
121 
128  void prepareReading(uint8_t address);
129 
133  void afterReading();
134 
135  // The enable pin is active low.
136  constexpr static uint8_t MUX_ENABLED = LOW;
137  constexpr static uint8_t MUX_DISABLED = HIGH;
138 };
139 
146 using CD74HC4067 = AnalogMultiplex<4>;
147 
154 using CD74HC4051 = AnalogMultiplex<3>;
155 
156 // -------------------------------------------------------------------------- //
157 
158 template <uint8_t N>
159 void AnalogMultiplex<N>::pinMode(pin_t, uint8_t mode) {
160  ExtIO::pinMode(analogPin, mode);
161 }
162 
163 template <uint8_t N>
164 int AnalogMultiplex<N>::digitalRead(pin_t pin) {
165  prepareReading(pin);
166  int result = ExtIO::digitalRead(analogPin);
167  afterReading();
168  return result;
169 }
170 
171 template <uint8_t N>
172 analog_t AnalogMultiplex<N>::analogRead(pin_t pin) {
173  prepareReading(pin);
174  ExtIO::analogRead(analogPin); // Discard first reading
175  analog_t result = ExtIO::analogRead(analogPin);
176  afterReading();
177  return result;
178 }
179 
180 template <uint8_t N>
181 void AnalogMultiplex<N>::begin() {
182  for (const pin_t &addressPin : addressPins)
183  ExtIO::pinMode(addressPin, OUTPUT);
184  if (enablePin != NO_PIN) {
185  ExtIO::pinMode(enablePin, OUTPUT);
186  ExtIO::digitalWrite(enablePin, MUX_DISABLED);
187  }
188 }
189 
190 template <uint8_t N>
191 void AnalogMultiplex<N>::setMuxAddress(uint8_t address) {
192  uint8_t mask = 1;
193  for (const pin_t &addressPin : addressPins) {
194  ExtIO::digitalWrite(addressPin, (address & mask) != 0);
195  mask <<= 1;
196  }
197 #if !defined(__AVR__) && !defined(__x86_64__)
198  delayMicroseconds(5);
199 #endif
200 }
201 
202 template <uint8_t N>
203 void AnalogMultiplex<N>::prepareReading(uint8_t address) {
204  setMuxAddress(address);
205  if (enablePin != NO_PIN)
206  ExtIO::digitalWrite(enablePin, MUX_ENABLED);
207 }
208 
209 template <uint8_t N>
210 void AnalogMultiplex<N>::afterReading() {
211  if (enablePin != NO_PIN)
212  ExtIO::digitalWrite(enablePin, MUX_DISABLED);
213 }
214 
215 END_AH_NAMESPACE
216 
217 AH_DIAGNOSTIC_POP()
Warnings.hpp
Array.hpp
AH::AnalogMultiplex
A class for reading multiplexed analog inputs.
Definition: AnalogMultiplex.hpp:28
StaticSizeExtendedIOElement.hpp
AH::StaticSizeExtendedIOElement
A class for ExtendedIOElements with a fixed size.
Definition: StaticSizeExtendedIOElement.hpp:19
AH_DIAGNOSTIC_WERROR
#define AH_DIAGNOSTIC_WERROR()
Definition: Warnings.hpp:16
BEGIN_AH_NAMESPACE
#define BEGIN_AH_NAMESPACE
Definition: AH/Settings/NamespaceSettings.hpp:9