Control Surface master
MIDI Control Surface library for Arduino
AnalogMultiplex.hpp
Go to the documentation of this file.
1/* ✔ */
2
3#pragma once
4
6AH_DIAGNOSTIC_WERROR() // Enable errors on warnings
7
8#include "ExtendedInputOutput.hpp"
11#include <stdlib.h>
12
14
27template <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, PinMode_t mode) override;
65
69 void pinModeBuffered(pin_t pin, PinMode_t mode) override;
70
75 void digitalWrite(pin_t, PinStatus_t) override // LCOV_EXCL_LINE
76 __attribute__((deprecated)) {} // LCOV_EXCL_LINE
77
81 void digitalWriteBuffered(pin_t, PinStatus_t) override // LCOV_EXCL_LINE
82 __attribute__((deprecated)) {} // LCOV_EXCL_LINE
83
90 PinStatus_t digitalRead(pin_t pin) override;
91
95 PinStatus_t digitalReadBuffered(pin_t pin) override;
96
103 analog_t analogRead(pin_t pin) override;
104
108 analog_t analogReadBuffered(pin_t pin) override;
109
114 void analogWrite(pin_t, analog_t) override // LCOV_EXCL_LINE
115 __attribute__((deprecated)) {} // LCOV_EXCL_LINE
116
120 void analogWriteBuffered(pin_t, analog_t) override // LCOV_EXCL_LINE
121 __attribute__((deprecated)) {} // LCOV_EXCL_LINE
122
127 void begin() override;
128
133 void updateBufferedOutputs() override {} // LCOV_EXCL_LINE
134
139 void updateBufferedInputs() override {} // LCOV_EXCL_LINE
140
145 void discardFirstReading(bool discardFirstReading_) {
146 this->discardFirstReading_ = discardFirstReading_;
147 }
148
149 private:
150 const pin_t analogPin;
151 const Array<pin_t, N> addressPins;
152 const pin_t enablePin;
153 bool discardFirstReading_ = true;
154
162 void setMuxAddress(uint8_t address);
163
170 void prepareReading(uint8_t address);
171
175 void afterReading();
176
177 // The enable pin is active low.
178 constexpr static auto MUX_ENABLED = LOW;
179 constexpr static auto MUX_DISABLED = HIGH;
180};
181
188using CD74HC4067 = AnalogMultiplex<4>;
189
196using CD74HC4051 = AnalogMultiplex<3>;
197
198// -------------------------------------------------------------------------- //
199
200template <uint8_t N>
201void AnalogMultiplex<N>::pinMode(pin_t, PinMode_t mode) {
202 ExtIO::pinMode(analogPin, mode);
203}
204
205template <uint8_t N>
206void AnalogMultiplex<N>::pinModeBuffered(pin_t, PinMode_t mode) {
207 AnalogMultiplex<N>::pinMode(analogPin, mode);
208}
209
210template <uint8_t N>
211PinStatus_t AnalogMultiplex<N>::digitalRead(pin_t pin) {
212 prepareReading(pin);
213 PinStatus_t result = ExtIO::digitalRead(analogPin);
214 afterReading();
215 return result;
216}
217
218template <uint8_t N>
219PinStatus_t AnalogMultiplex<N>::digitalReadBuffered(pin_t pin) {
220 return AnalogMultiplex<N>::digitalRead(pin);
221}
222
223template <uint8_t N>
224analog_t AnalogMultiplex<N>::analogRead(pin_t pin) {
225 prepareReading(pin);
226 if (discardFirstReading_)
227 (void)ExtIO::analogRead(analogPin); // Discard first reading
228 analog_t result = ExtIO::analogRead(analogPin);
229 afterReading();
230 return result;
231}
232
233template <uint8_t N>
234analog_t AnalogMultiplex<N>::analogReadBuffered(pin_t pin) {
235 return AnalogMultiplex<N>::analogRead(pin);
236}
237
238template <uint8_t N>
239void AnalogMultiplex<N>::begin() {
240 for (const pin_t &addressPin : addressPins)
241 ExtIO::pinMode(addressPin, OUTPUT);
242 if (enablePin != NO_PIN) {
243 ExtIO::pinMode(enablePin, OUTPUT);
244 ExtIO::digitalWrite(enablePin, MUX_DISABLED);
245 }
246}
247
248template <uint8_t N>
249void AnalogMultiplex<N>::setMuxAddress(uint8_t address) {
250 uint8_t mask = 1;
251 for (const pin_t &addressPin : addressPins) {
252 ExtIO::digitalWrite(addressPin, (address & mask) != 0 ? HIGH : LOW);
253 mask <<= 1;
254 }
255#if !defined(__AVR__) && defined(ARDUINO)
256 delayMicroseconds(1);
257#endif
258}
259
260template <uint8_t N>
261void AnalogMultiplex<N>::prepareReading(uint8_t address) {
262 setMuxAddress(address);
263 if (enablePin != NO_PIN)
264 ExtIO::digitalWrite(enablePin, MUX_ENABLED);
265}
266
267template <uint8_t N>
268void AnalogMultiplex<N>::afterReading() {
269 if (enablePin != NO_PIN)
270 ExtIO::digitalWrite(enablePin, MUX_DISABLED);
271}
272
273END_AH_NAMESPACE
274
275AH_DIAGNOSTIC_POP()
#define BEGIN_AH_NAMESPACE
#define AH_DIAGNOSTIC_WERROR()
Definition: Warnings.hpp:35
A class for reading multiplexed analog inputs.
A class for ExtendedIOElements with a fixed size.