Control Surface main
MIDI Control Surface library for Arduino
Loading...
Searching...
No Matches
AnalogMultiplex.hpp
Go to the documentation of this file.
1/* ✔ */
2
3#pragma once
4
8#include <stdlib.h>
9
11
24template <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(pin_int_t pin, PinMode_t mode) override;
62
66 void pinModeBuffered(pin_int_t pin, PinMode_t mode) override;
67
72 void digitalWrite(pin_int_t, PinStatus_t) override // LCOV_EXCL_LINE
73 __attribute__((deprecated)) {} // LCOV_EXCL_LINE
74
78 void digitalWriteBuffered(pin_int_t, PinStatus_t) override // LCOV_EXCL_LINE
79 __attribute__((deprecated)) {} // LCOV_EXCL_LINE
80
87 PinStatus_t digitalRead(pin_int_t pin) override;
88
92 PinStatus_t digitalReadBuffered(pin_int_t pin) override;
93
100 analog_t analogRead(pin_int_t pin) override;
101
105 analog_t analogReadBuffered(pin_int_t pin) override;
106
111 void analogWrite(pin_int_t, analog_t) override // LCOV_EXCL_LINE
112 __attribute__((deprecated)) {} // LCOV_EXCL_LINE
113
117 void analogWriteBuffered(pin_int_t, analog_t) override // LCOV_EXCL_LINE
118 __attribute__((deprecated)) {} // LCOV_EXCL_LINE
119
124 void begin() override;
125
130 void updateBufferedOutputs() override {} // LCOV_EXCL_LINE
131
136 void updateBufferedInputs() override {} // LCOV_EXCL_LINE
137
142 void discardFirstReading(bool discardFirstReading_) {
143 this->discardFirstReading_ = discardFirstReading_;
144 }
145
146 protected:
147 const pin_t analogPin;
148 const Array<pin_t, N> addressPins;
149 const pin_t enablePin;
150 bool discardFirstReading_ = true;
151
159 void setMuxAddress(uint8_t address);
160
167 void prepareReading(uint8_t address);
168
172 void afterReading();
173
174 // The enable pin is active low.
175 constexpr static auto MUX_ENABLED = LOW;
176 constexpr static auto MUX_DISABLED = HIGH;
177};
178
185using CD74HC4067 = AnalogMultiplex<4>;
186
193using CD74HC4051 = AnalogMultiplex<3>;
194
195// -------------------------------------------------------------------------- //
196
197template <uint8_t N>
198void AnalogMultiplex<N>::pinMode(pin_int_t, PinMode_t mode) {
199 ExtIO::pinMode(analogPin, mode);
200}
201
202template <uint8_t N>
203void AnalogMultiplex<N>::pinModeBuffered(pin_int_t p, PinMode_t mode) {
204 AnalogMultiplex<N>::pinMode(p, mode);
205}
206
207template <uint8_t N>
208PinStatus_t AnalogMultiplex<N>::digitalRead(pin_int_t pin) {
209 prepareReading(static_cast<uint8_t>(pin));
210 PinStatus_t result = ExtIO::digitalRead(analogPin);
211 afterReading();
212 return result;
213}
214
215template <uint8_t N>
216PinStatus_t AnalogMultiplex<N>::digitalReadBuffered(pin_int_t pin) {
217 return AnalogMultiplex<N>::digitalRead(pin);
218}
219
220template <uint8_t N>
221analog_t AnalogMultiplex<N>::analogRead(pin_int_t pin) {
222 prepareReading(static_cast<uint8_t>(pin));
223 if (discardFirstReading_)
224 (void)ExtIO::analogRead(analogPin); // Discard first reading
225 analog_t result = ExtIO::analogRead(analogPin);
226 afterReading();
227 return result;
228}
229
230template <uint8_t N>
231analog_t AnalogMultiplex<N>::analogReadBuffered(pin_int_t pin) {
232 return AnalogMultiplex<N>::analogRead(pin);
233}
234
235template <uint8_t N>
236void AnalogMultiplex<N>::begin() {
237 for (const pin_t &addressPin : addressPins)
238 ExtIO::pinMode(addressPin, OUTPUT);
239 if (enablePin != NO_PIN) {
240 ExtIO::pinMode(enablePin, OUTPUT);
241 ExtIO::digitalWrite(enablePin, MUX_DISABLED);
242 }
243}
244
245template <uint8_t N>
246void AnalogMultiplex<N>::setMuxAddress(uint8_t address) {
247 uint8_t mask = 1;
248 for (const pin_t &addressPin : addressPins) {
249 ExtIO::digitalWrite(addressPin, (address & mask) != 0 ? HIGH : LOW);
250 mask <<= 1;
251 }
252#if !defined(__AVR__) && defined(ARDUINO)
253 delayMicroseconds(SELECT_LINE_DELAY);
254#endif
255}
256
257template <uint8_t N>
258void AnalogMultiplex<N>::prepareReading(uint8_t address) {
259 setMuxAddress(address);
260 if (enablePin != NO_PIN)
261 ExtIO::digitalWrite(enablePin, MUX_ENABLED);
262}
263
264template <uint8_t N>
265void AnalogMultiplex<N>::afterReading() {
266 if (enablePin != NO_PIN)
267 ExtIO::digitalWrite(enablePin, MUX_DISABLED);
268}
269
270END_AH_NAMESPACE
#define BEGIN_AH_NAMESPACE
A class for reading multiplexed analog inputs.
A class for ExtendedIOElements with a fixed size.