OpenSourceSimWheelESP32
Open-source wireless steering wheel/button box for ESP32 boards
Loading...
Searching...
No Matches
InputHardware.hpp
Go to the documentation of this file.
1
12#pragma once
13
14//-------------------------------------------------------------------
15// Imports
16//-------------------------------------------------------------------
17
18#include "InternalTypes.hpp" // For BitQueue
20#include <initializer_list>
21
22//-------------------------------------------------------------------
23// (Abstract) DigitalInput
24//-------------------------------------------------------------------
25
33{
34public:
35 virtual ~DigitalInput() noexcept {}
36
49 virtual void read(uint128_t &state) = 0;
50};
51
52//-------------------------------------------------------------------
53// Single button
54//-------------------------------------------------------------------
55
61{
62protected:
66 uint8_t inputNumber;
67
68public:
76
77 virtual void read(uint128_t &state) override;
78};
79
80//-------------------------------------------------------------------
81// Rotary encoder
82//-------------------------------------------------------------------
83
89{
90private:
91 InputGPIO clkPin, dtPin; // pins
92 uint8_t code; // State of the decoding algorithm
93 uint16_t sequence; // Last sequence of states
94 uint8_t cwButton;
95 uint8_t ccwButton;
96 BitQueue queue;
97 bool cwOrCcw;
98
99 // duration of the current "pulse" event in polling cycles
100 uint8_t currentPulseWidth;
101
102 // a "virtual button" press event was notified at read(),
103 // so a release event must be notified next
104 bool pressEventNotified;
105
106 static void isrh(void *instance);
107 static void isrhAlternateEncoding(void *instance);
108
109public:
116 inline static uint8_t pulseMultiplier = 1;
117
135 InputGPIO clkPin,
136 InputGPIO dtPin,
137 InputNumber cwButtonNumber,
138 InputNumber ccwButtonNumber,
139 bool useAlternateEncoding = false);
140
149 static bool setPulseMultiplier(uint8_t multiplier)
150 {
151 if ((multiplier > 0) && (multiplier < 7) &&
152 (pulseMultiplier != multiplier))
153 {
154 pulseMultiplier = multiplier;
155 return true;
156 }
157 return false;
158 };
159
160 virtual void read(uint128_t &state) override;
161};
162
163//-------------------------------------------------------------------
164// Button matrix
165//-------------------------------------------------------------------
166
172{
173private:
174 // InputGPIOCollection inputPins = {};
175 // OutputGPIOCollection outputPins = {};
176 ButtonMatrix matrix;
177 bool negativeLogic;
178
179public:
187 const ButtonMatrix &matrix,
188 bool negativeLogic = false);
189
190 virtual void read(uint128_t &state) override;
191};
192
193//-------------------------------------------------------------------
194// Analog Multiplexers
195//-------------------------------------------------------------------
196
204{
205private:
206 ::std::vector<OutputGPIO> selectorPins{};
207 ::std::vector<InputGPIO> inputPins{};
208 ::std::vector<uint8_t> inputNumber{};
209
210public:
220 OutputGPIO selectorPin1,
221 OutputGPIO selectorPin2,
222 OutputGPIO selectorPin3,
224
235 OutputGPIO selectorPin1,
236 OutputGPIO selectorPin2,
237 OutputGPIO selectorPin3,
238 OutputGPIO selectorPin4,
240
252 OutputGPIO selectorPin1,
253 OutputGPIO selectorPin2,
254 OutputGPIO selectorPin3,
255 OutputGPIO selectorPin4,
256 OutputGPIO selectorPin5,
258
259 virtual void read(uint128_t &state) override;
260
261private:
262 void initializeMux(
263 ::std::initializer_list<OutputGPIO> selectorPins,
264 const ::std::vector<InputGPIO> &inputPins);
265};
266
267//-------------------------------------------------------------------
268// I2C input hardware
269//-------------------------------------------------------------------
270
276class I2CInput : public DigitalInput // : public I2CInput
277{
278protected:
280 void *device = nullptr;
281
282public:
291 uint8_t address7Bits,
292 I2CBus bus = I2CBus::PRIMARY,
293 uint8_t max_speed_mult = 1);
294
295 virtual ~I2CInput();
296};
297
303{
304private:
305 PCF8574Expander inputNumbers;
306 bool getGPIOstate(uint8_t &state);
307
308public:
317 const PCF8574Expander &inputNumbers,
318 uint8_t address7Bits,
319 I2CBus bus = I2CBus::PRIMARY);
320
321 virtual void read(uint128_t &state) override;
322};
323
329{
330private:
331 MCP23017Expander inputNumbers;
332 bool getGPIOstate(uint16_t &state);
333 void configure();
334
335public:
344 const MCP23017Expander &inputNumbers,
345 uint8_t address7Bits,
346 I2CBus bus = I2CBus::PRIMARY);
347
348 virtual void read(uint128_t &state) override;
349};
350
351//-------------------------------------------------------------------
352// Shift registers
353//-------------------------------------------------------------------
354
360{
361private:
362 size_t switchCount;
363 InputGPIO serialPin;
364 OutputGPIO loadPin;
365 OutputGPIO nextPin;
366 ::std::vector<uint8_t> inputNumber{};
367 bool loadHighOrLow;
368 bool nextHighToLowOrLowToHigh;
369 bool negativeLogic;
370
371public:
396 OutputGPIO loadPin,
397 OutputGPIO nextPin,
398 InputGPIO inputPin,
399 const ShiftRegisterChain &chain,
400 InputNumber SER_inputNumber = UNSPECIFIED::VALUE,
401 const bool loadHighOrLow = false,
402 const bool nextHighToLowOrLowToHigh = false,
403 const bool negativeLogic = true);
404
405 virtual void read(uint128_t &state) override;
406};
407
408//-------------------------------------------------------------------
409// Potentiometers
410//-------------------------------------------------------------------
411
417{
418public:
425 virtual void getCalibrationData(int &minReading, int &maxReading) = 0;
426
433 virtual void setCalibrationData(int minReading, int maxReading) = 0;
434
439 virtual void resetCalibrationData() = 0;
440
449 virtual void read(uint8_t &value, bool &autoCalibrated) = 0;
450
451 virtual ~AnalogInput() noexcept {}
452};
453
459{
460protected:
470 uint8_t lastValue;
471
472public:
479
480 void resetCalibrationData() override;
481
482 void getCalibrationData(int &minReading, int &maxReading) override;
483
484 void setCalibrationData(int minReading, int maxReading) override;
485
486 void read(uint8_t &value, bool &autoCalibrated) override;
487};
488
496{
497protected:
498 ADC_GPIO xAxisPin;
499 ADC_GPIO yAxisPin;
500 uint8_t up;
501 uint8_t down;
502 uint8_t left;
503 uint8_t right;
504 int upAdcReading;
505 int downAdcReading;
506 int leftAdcReading;
507 int rightAdcReading;
508 bool xAxisReverse;
509 bool AxisReverse;
510
511public:
539 ADC_GPIO xAxisPin,
540 ADC_GPIO yAxisPin,
541 InputNumber up,
542 InputNumber down,
543 InputNumber left,
544 InputNumber right,
545 uint8_t xCenter = 127,
546 uint8_t yCenter = 127,
547 uint8_t xDeadZone = 63,
548 uint8_t yDeadZone = 63,
549 bool xAxisReverse = false,
550 bool yAxisReverse = false);
551
552 virtual void read(uint128_t &state) override;
553};
554
555//-------------------------------------------------------------------
556// Fake input hardware for testing
557//-------------------------------------------------------------------
558
564{
565private:
566 FakeInput *_instance;
567
568public:
574 FakeDigitalInput(FakeInput *instance) { _instance = instance; }
575
576 virtual void read(uint128_t &state) override
577 {
578 // for (uint8_t i = 0; i < 128; i++)
579 // if (!_instance.mask.bit(i))
580 // state.set_bit(i, _instance.bit(i));
581 state = (state & (_instance->mask)) |
582 (_instance->state & ~(_instance->mask));
583 }
584};
585
590class FakeAxis : public AnalogInput
591{
592private:
593 FakeInput *_instance;
594 bool _leftOrRight;
595
596public:
604 FakeAxis(FakeInput *instance, bool leftOrRight)
605 {
606 _leftOrRight = leftOrRight;
607 _instance = instance;
608 }
609
610 void resetCalibrationData() override
611 {
612 _instance->recalibrationRequestCount++;
613 };
614
615 void getCalibrationData(int &minReading, int &maxReading) override
616 {
617 minReading = 0;
618 maxReading = 254;
619 }
620
621 void setCalibrationData(int minReading, int maxReading) override {};
622
623 void read(uint8_t &value, bool &autoCalibrated)
624 {
625 autoCalibrated = false;
626 if (_leftOrRight)
627 value = _instance->leftAxis;
628 else
629 value = _instance->rightAxis;
630 };
631};
Configure input hardware and specify input numbers.
GPIOExpanderChip< PCF8574Pin > PCF8574Expander
PCF8574 GPIO Expander for switches.
std::vector< AnalogMultiplexerChip< PinTags > > AnalogMultiplexerGroup
Group of analog multiplexer chips sharing the same selector pins.
std::vector< ShiftRegisterChip > ShiftRegisterChain
Chain of PISO shift registers for switches.
std::map< OutputGPIO, std::map< InputGPIO, InputNumber > > ButtonMatrix
Button matrix specification.
GPIOExpanderChip< MCP23017Pin > MCP23017Expander
MCP23017 GPIO Expander for switches.
Types and constants used everywhere for firmware implementation.
@ VALUE
Unspecified value.
I2CBus
I2C bus controller.
Class for analog clutch paddles.
int minADCReading
Minimum ADC reading for auto-calibration.
ADC_GPIO pinNumber
Configured ADC pin.
int maxADCReading
Maximum ADC reading for auto-calibration.
int lastADCReading
Last ADC reading.
void resetCalibrationData() override
Force auto-calibration.
AnalogClutchInput(ADC_GPIO pinNumber)
Construct a new Analog Clutch Input object.
void getCalibrationData(int &minReading, int &maxReading) override
Get auto-calibration data. Required for persistent storage.
uint8_t lastValue
Last axis position.
void setCalibrationData(int minReading, int maxReading) override
Set auto-calibration data (loaded from persistent storage).
void read(uint8_t &value, bool &autoCalibrated) override
Read current axis position. The axis must go from one end to the other for auto- calibration.
Class for all polled analog inputs (axis)
virtual void setCalibrationData(int minReading, int maxReading)=0
Set auto-calibration data (loaded from persistent storage).
virtual void getCalibrationData(int &minReading, int &maxReading)=0
Get auto-calibration data. Required for persistent storage.
virtual void resetCalibrationData()=0
Force auto-calibration.
virtual void read(uint8_t &value, bool &autoCalibrated)=0
Read current axis position. The axis must go from one end to the other for auto- calibration.
Analog joystick as directional input.
AnalogJoystickInput(ADC_GPIO xAxisPin, ADC_GPIO yAxisPin, InputNumber up, InputNumber down, InputNumber left, InputNumber right, uint8_t xCenter=127, uint8_t yCenter=127, uint8_t xDeadZone=63, uint8_t yDeadZone=63, bool xAxisReverse=false, bool yAxisReverse=false)
Construct a new Analog Joystick Input object.
virtual void read(uint128_t &state) override
Read the current state of the inputs (pressed or released)
State of switches connected to analog multiplexers.
AnalogMultiplexerInput(OutputGPIO selectorPin1, OutputGPIO selectorPin2, OutputGPIO selectorPin3, const AnalogMultiplexerGroup< Mux8Pin > &chips)
Construct a new Analog Multiplexer Input object.
virtual void read(uint128_t &state) override
Read the current state of the inputs (pressed or released)
AnalogMultiplexerInput(OutputGPIO selectorPin1, OutputGPIO selectorPin2, OutputGPIO selectorPin3, OutputGPIO selectorPin4, const AnalogMultiplexerGroup< Mux16Pin > &chips)
Construct a new Analog Multiplexer Input object.
AnalogMultiplexerInput(OutputGPIO selectorPin1, OutputGPIO selectorPin2, OutputGPIO selectorPin3, OutputGPIO selectorPin4, OutputGPIO selectorPin5, const AnalogMultiplexerGroup< Mux32Pin > &chips)
Construct a new Analog Multiplexer Input object.
Queue for 61 bits.
Button matrix hardware.
virtual void read(uint128_t &state) override
Read the current state of the inputs (pressed or released)
ButtonMatrixInput(const ButtonMatrix &matrix, bool negativeLogic=false)
Construct a new Button Matrix Input object.
Single button.
uint8_t inputNumber
Input bitmap.
InputGPIO pinNumber
Configured input pin.
DigitalButton(InputGPIO pinNumber, InputNumber buttonNumber)
Construct a new Digital Button object.
virtual void read(uint128_t &state) override
Read the current state of the inputs (pressed or released)
Base class for all polled switches.
virtual void read(uint128_t &state)=0
Read the current state of the inputs (pressed or released)
Fake analog input for testing.
void getCalibrationData(int &minReading, int &maxReading) override
Get auto-calibration data. Required for persistent storage.
void resetCalibrationData() override
Force auto-calibration.
void setCalibrationData(int minReading, int maxReading) override
Set auto-calibration data (loaded from persistent storage).
FakeAxis(FakeInput *instance, bool leftOrRight)
Construct a new Fake Digital Input object.
void read(uint8_t &value, bool &autoCalibrated)
Read current axis position. The axis must go from one end to the other for auto- calibration.
Fake digital input for testing.
virtual void read(uint128_t &state) override
Read the current state of the inputs (pressed or released)
FakeDigitalInput(FakeInput *instance)
Construct a new Fake Digital Input object.
Base class for switches/buttons attached to an I2C GPIO expander.
void * device
Slave device in the I2C API (must be type-casted)
I2CInput(uint8_t address7Bits, I2CBus bus=I2CBus::PRIMARY, uint8_t max_speed_mult=1)
Construct a new I2CButtonsInput object.
Class for buttons attached to a MCP23017 GPIO expander.
virtual void read(uint128_t &state) override
Read the current state of the inputs (pressed or released)
MCP23017ButtonsInput(const MCP23017Expander &inputNumbers, uint8_t address7Bits, I2CBus bus=I2CBus::PRIMARY)
Construct a new MCP23017ButtonsInput object.
Class for buttons attached to a PCF8574 GPIO expander.
virtual void read(uint128_t &state) override
Read the current state of the inputs (pressed or released)
PCF8574ButtonsInput(const PCF8574Expander &inputNumbers, uint8_t address7Bits, I2CBus bus=I2CBus::PRIMARY)
Construct a new PCF8574ButtonsInput object.
Relative Rotary Encoder.
virtual void read(uint128_t &state) override
Read the current state of the inputs (pressed or released)
static bool setPulseMultiplier(uint8_t multiplier)
Set a time multiplier for "pulse" events.
static uint8_t pulseMultiplier
Pulse multiplier for rotary encoders.
RotaryEncoderInput(InputGPIO clkPin, InputGPIO dtPin, InputNumber cwButtonNumber, InputNumber ccwButtonNumber, bool useAlternateEncoding=false)
Construct a new Rotary Encoder Input object.
State of switches connected to PISO shift registers.
ShiftRegistersInput(OutputGPIO loadPin, OutputGPIO nextPin, InputGPIO inputPin, const ShiftRegisterChain &chain, InputNumber SER_inputNumber=UNSPECIFIED::VALUE, const bool loadHighOrLow=false, const bool nextHighToLowOrLowToHigh=false, const bool negativeLogic=true)
Construct a new Shift Registers Input object.
virtual void read(uint128_t &state) override
Read the current state of the inputs (pressed or released)
ADC-capable GPIO pin number.
Fake input specification used for testing.
uint8_t leftAxis
Left axis position.
uint8_t rightAxis
Right axis position.
size_t recalibrationRequestCount
Count of times axis recalibration was asked.
uint128_t mask
Input mask.
uint128_t state
Input bitmap.
Input-capable GPIO pin number.
Firmware-defined input numbers in the range [0,127] or unspecified.
Output-capable GPIO pin number.
128-bit integer