This is an old version of the documentation. View the latest version here.
Control Surface  1.0.0
MIDI Control Surface library for Arduino
AnalogMultiplex.hpp
Go to the documentation of this file.
1 /* ✔ */
2 
3 #pragma once
4 
7 #include <Helpers/Array.hpp>
8 #include <stdlib.h>
9 
11 
24 template <uint8_t N>
26  public:
41  AnalogMultiplex(pin_t analogPin, const Array<pin_t, N> &addressPins,
42  pin_t enablePin = NO_PIN)
43  : analogPin(analogPin), addressPins(addressPins), enablePin(enablePin) {
44  }
45 
61  void pinMode(UNUSED_PARAM pin_t pin, uint8_t mode) override;
62 
67  void digitalWrite(UNUSED_PARAM pin_t pin, UNUSED_PARAM uint8_t val) override
68  __attribute__((deprecated)) {}
69 
76  int digitalRead(pin_t pin) override;
77 
84  analog_t analogRead(pin_t pin) override;
85 
90  void analogWrite(UNUSED_PARAM pin_t pin, UNUSED_PARAM analog_t val) override
91  __attribute__((deprecated)) {}
92 
97  void begin() override;
98 
103  void update() override {}
104 
105  private:
106  const pin_t analogPin;
107  const Array<pin_t, N> addressPins;
108  const pin_t enablePin;
109 
117  void setMuxAddress(uint8_t address);
118 
125  void prepareReading(uint8_t address);
126 
130  void afterReading();
131 
132  // The enable pin is active low.
133  constexpr static uint8_t MUX_ENABLED = LOW;
134  constexpr static uint8_t MUX_DISABLED = HIGH;
135 };
136 
143 using CD74HC4067 = AnalogMultiplex<4>;
144 
151 using CD74HC4051 = AnalogMultiplex<3>;
152 
153 // -------------------------------------------------------------------------- //
154 
155 template <uint8_t N>
156 void AnalogMultiplex<N>::pinMode(pin_t, uint8_t mode) {
157  ExtIO::pinMode(analogPin, mode);
158 }
159 
160 template <uint8_t N>
161 int AnalogMultiplex<N>::digitalRead(pin_t pin) {
162  prepareReading(pin);
163  int result = ExtIO::digitalRead(analogPin);
164  afterReading();
165  return result;
166 }
167 
168 template <uint8_t N>
169 analog_t AnalogMultiplex<N>::analogRead(pin_t pin) {
170  prepareReading(pin);
171  ExtIO::analogRead(analogPin); // Discard first reading
172  analog_t result = ExtIO::analogRead(analogPin);
173  afterReading();
174  return result;
175 }
176 
177 template <uint8_t N>
178 void AnalogMultiplex<N>::begin() {
179  for (const pin_t &addressPin : addressPins)
180  ExtIO::pinMode(addressPin, OUTPUT);
181  if (enablePin != NO_PIN) {
182  ExtIO::pinMode(enablePin, OUTPUT);
183  ExtIO::digitalWrite(enablePin, MUX_DISABLED);
184  }
185 }
186 
187 template <uint8_t N>
188 void AnalogMultiplex<N>::setMuxAddress(uint8_t address) {
189  uint8_t mask = 1;
190  for (const pin_t &addressPin : addressPins) {
191  ExtIO::digitalWrite(addressPin, (address & mask) != 0);
192  mask <<= 1;
193  }
194 #if !defined(__AVR__) && !defined(__x86_64__)
195  delayMicroseconds(5);
196 #endif
197 }
198 
199 template <uint8_t N>
200 void AnalogMultiplex<N>::prepareReading(uint8_t address) {
201  setMuxAddress(address);
202  if (enablePin != NO_PIN)
203  ExtIO::digitalWrite(enablePin, MUX_ENABLED);
204 }
205 
206 template <uint8_t N>
207 void AnalogMultiplex<N>::afterReading() {
208  if (enablePin != NO_PIN)
209  ExtIO::digitalWrite(enablePin, MUX_DISABLED);
210 }
211 
212 END_CS_NAMESPACE
StaticSizeExtendedIOElement
A class for ExtendedIOElements with a fixed size.
Definition: StaticSizeExtendedIOElement.hpp:16
ExtendedInputOutput.hpp
Array.hpp
BEGIN_CS_NAMESPACE
#define BEGIN_CS_NAMESPACE
Definition: NamespaceSettings.hpp:9
AnalogMultiplex
A class for reading multiplexed analog inputs.
Definition: AnalogMultiplex.hpp:25
StaticSizeExtendedIOElement.hpp