Skip to content

Commit 41403d1

Browse files
authored
Merge pull request #17 from dmadison/unused-pin
Unused pin rework
2 parents 053c24c + 1da6619 commit 41403d1

2 files changed

Lines changed: 87 additions & 56 deletions

File tree

src/SimRacing.cpp

Lines changed: 45 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,21 @@
2929

3030
namespace SimRacing {
3131

32+
/**
33+
* Take a pin number as an input and sanitize it to a known working value
34+
*
35+
* In an ideal world this would check against the available pins on the micro,
36+
* but as far as I know the Arduino API does not have a "valid pin" function.
37+
* Instead, we'll just accept any positive number as a pin and reject any
38+
* negative number as invalid ("Unused").
39+
*
40+
* @param pin the pin number to sanitize
41+
* @returns the pin number, or UnusedPin
42+
*/
43+
static constexpr PinNum sanitizePin(PinNum pin) {
44+
return pin < 0 ? UnusedPin : pin;
45+
}
46+
3247

3348
/**
3449
* Invert an input value so it's at the same relative position
@@ -161,9 +176,9 @@ static void readFloat(float& value, Stream& client) {
161176
// DeviceConnection #
162177
//#########################################################
163178

164-
DeviceConnection::DeviceConnection(uint8_t pin, bool invert, unsigned long detectTime)
179+
DeviceConnection::DeviceConnection(PinNum pin, bool invert, unsigned long detectTime)
165180
:
166-
Pin(pin), Inverted(invert), stablePeriod(detectTime), // constants(ish)
181+
pin(sanitizePin(pin)), inverted(invert), stablePeriod(detectTime), // constants(ish)
167182

168183
/* Assume we're connected on first call
169184
*/
@@ -177,7 +192,7 @@ DeviceConnection::DeviceConnection(uint8_t pin, bool invert, unsigned long detec
177192
* the device to be read as connected as soon as the board turns on, without
178193
* having to wait an arbitrary amount.
179194
*/
180-
pinState(!Inverted),
195+
pinState(!inverted),
181196

182197
/* Set the last pin change to right now minus the stable period so it's
183198
* read as being already stable. Again, this will make the class return
@@ -186,7 +201,9 @@ DeviceConnection::DeviceConnection(uint8_t pin, bool invert, unsigned long detec
186201
lastChange(millis() - detectTime)
187202

188203
{
189-
pinMode(Pin, INPUT); // set pin as input, *no* pull-up
204+
if (pin != UnusedPin) {
205+
pinMode(pin, INPUT); // set pin as input, *no* pull-up
206+
}
190207
}
191208

192209
void DeviceConnection::poll() {
@@ -248,30 +265,30 @@ void DeviceConnection::setStablePeriod(unsigned long t) {
248265
}
249266

250267
bool DeviceConnection::readPin() const {
251-
if (Pin == NOT_A_PIN) return HIGH; // if no pin is set, we're always connected
252-
const bool state = digitalRead(Pin);
253-
return Inverted ? !state : state;
268+
if (pin == UnusedPin) return HIGH; // if no pin is set, we're always connected
269+
const bool state = digitalRead(pin);
270+
return inverted ? !state : state;
254271
}
255272

256273
//#########################################################
257274
// AnalogInput #
258275
//#########################################################
259276

260277

261-
AnalogInput::AnalogInput(uint8_t p)
262-
: Pin(p), position(AnalogInput::Min), cal({AnalogInput::Min, AnalogInput::Max})
278+
AnalogInput::AnalogInput(PinNum pin)
279+
: pin(sanitizePin(pin)), position(AnalogInput::Min), cal({AnalogInput::Min, AnalogInput::Max})
263280
{
264-
if (Pin != NOT_A_PIN) {
265-
pinMode(Pin, INPUT);
281+
if (pin != UnusedPin) {
282+
pinMode(pin, INPUT);
266283
}
267284
}
268285

269286
bool AnalogInput::read() {
270287
bool changed = false;
271288

272-
if (Pin != NOT_A_PIN) {
289+
if (pin != UnusedPin) {
273290
const int previous = this->position;
274-
this->position = analogRead(Pin);
291+
this->position = analogRead(pin);
275292

276293
// check if value is different for 'changed' flag
277294
if (previous != this->position) {
@@ -333,7 +350,7 @@ void AnalogInput::setCalibration(AnalogInput::Calibration newCal) {
333350
// Pedals #
334351
//#########################################################
335352

336-
Pedals::Pedals(AnalogInput* dataPtr, uint8_t nPedals, uint8_t detectPin)
353+
Pedals::Pedals(AnalogInput* dataPtr, uint8_t nPedals, PinNum detectPin)
337354
:
338355
pedalData(dataPtr),
339356
NumPedals(nPedals),
@@ -538,7 +555,7 @@ void Pedals::serialCalibration(Stream& iface) {
538555
}
539556

540557

541-
TwoPedals::TwoPedals(uint8_t gasPin, uint8_t brakePin, uint8_t detectPin)
558+
TwoPedals::TwoPedals(PinNum gasPin, PinNum brakePin, PinNum detectPin)
542559
: Pedals(pedalData, NumPedals, detectPin),
543560
pedalData{ AnalogInput(gasPin), AnalogInput(brakePin) }
544561
{}
@@ -549,7 +566,7 @@ void TwoPedals::setCalibration(AnalogInput::Calibration gasCal, AnalogInput::Cal
549566
}
550567

551568

552-
ThreePedals::ThreePedals(uint8_t gasPin, uint8_t brakePin, uint8_t clutchPin, uint8_t detectPin)
569+
ThreePedals::ThreePedals(PinNum gasPin, PinNum brakePin, PinNum clutchPin, PinNum detectPin)
553570
: Pedals(pedalData, NumPedals, detectPin),
554571
pedalData{ AnalogInput(gasPin), AnalogInput(brakePin), AnalogInput(clutchPin) }
555572
{}
@@ -562,7 +579,7 @@ void ThreePedals::setCalibration(AnalogInput::Calibration gasCal, AnalogInput::C
562579

563580

564581

565-
LogitechPedals::LogitechPedals(uint8_t gasPin, uint8_t brakePin, uint8_t clutchPin, uint8_t detectPin)
582+
LogitechPedals::LogitechPedals(PinNum gasPin, PinNum brakePin, PinNum clutchPin, PinNum detectPin)
566583
: ThreePedals(gasPin, brakePin, clutchPin, detectPin)
567584
{
568585
// taken from calibrating my own pedals. the springs are pretty stiff so while
@@ -571,7 +588,7 @@ LogitechPedals::LogitechPedals(uint8_t gasPin, uint8_t brakePin, uint8_t clutchP
571588
this->setCalibration({ 904, 48 }, { 944, 286 }, { 881, 59 });
572589
}
573590

574-
LogitechDrivingForceGT_Pedals::LogitechDrivingForceGT_Pedals(uint8_t gasPin, uint8_t brakePin, uint8_t detectPin)
591+
LogitechDrivingForceGT_Pedals::LogitechDrivingForceGT_Pedals(PinNum gasPin, PinNum brakePin, PinNum detectPin)
575592
: TwoPedals(gasPin, brakePin, detectPin)
576593
{
577594
this->setCalibration({ 646, 0 }, { 473, 1023 }); // taken from calibrating my own pedals
@@ -657,22 +674,24 @@ const float AnalogShifter::CalEngagementPoint = 0.70;
657674
const float AnalogShifter::CalReleasePoint = 0.50;
658675
const float AnalogShifter::CalEdgeOffset = 0.60;
659676

660-
AnalogShifter::AnalogShifter(uint8_t pinX, uint8_t pinY, uint8_t pinRev, uint8_t detectPin)
677+
AnalogShifter::AnalogShifter(PinNum pinX, PinNum pinY, PinNum pinRev, PinNum detectPin)
661678
:
662679
/* In initializing the Shifter, the lowest gear is going to be '-1' if a pin
663680
* exists for reverse, otherwise it's going to be '0' (neutral).
664681
*/
665-
Shifter(pinRev != NOT_A_PIN ? -1 : 0, 6),
682+
Shifter(sanitizePin(pinRev) != UnusedPin ? -1 : 0, 6),
666683

667684
/* Two axes, X and Y */
668685
analogAxis{ AnalogInput(pinX), AnalogInput(pinY) },
669686

670-
PinReverse(pinRev),
687+
pinReverse(sanitizePin(pinRev)),
671688
detector(detectPin, false) // not inverted
672689
{}
673690

674691
void AnalogShifter::begin() {
675-
pinMode(PinReverse, INPUT);
692+
if (this->pinReverse != UnusedPin) {
693+
pinMode(pinReverse, INPUT);
694+
}
676695
update(); // set initial gear position
677696
}
678697

@@ -777,10 +796,10 @@ int AnalogShifter::getPositionRaw(Axis ax) const {
777796
bool AnalogShifter::getReverseButton() const {
778797
// if the reverse pin is not set *or* if the device is not currently
779798
// connected, avoid reading the floating input and just return 'false'
780-
if (PinReverse == NOT_A_PIN || detector.getState() != DeviceConnection::Connected) {
799+
if (pinReverse == UnusedPin || detector.getState() != DeviceConnection::Connected) {
781800
return false;
782801
}
783-
return digitalRead(PinReverse);
802+
return digitalRead(pinReverse);
784803
}
785804

786805
void AnalogShifter::setCalibration(
@@ -977,7 +996,7 @@ void AnalogShifter::serialCalibration(Stream& iface) {
977996
iface.println(F("\n\nCalibration complete! :)\n"));
978997
}
979998

980-
LogitechShifter::LogitechShifter(uint8_t pinX, uint8_t pinY, uint8_t pinRev, uint8_t detectPin)
999+
LogitechShifter::LogitechShifter(PinNum pinX, PinNum pinY, PinNum pinRev, PinNum detectPin)
9811000
: AnalogShifter(pinX, pinY, pinRev, detectPin)
9821001
{
9831002
this->setCalibration({ 490, 440 }, { 253, 799 }, { 262, 86 }, { 460, 826 }, { 470, 76 }, { 664, 841 }, { 677, 77 });
@@ -987,7 +1006,7 @@ LogitechShifter::LogitechShifter(uint8_t pinX, uint8_t pinY, uint8_t pinRev, uin
9871006
// Handbrake #
9881007
//#########################################################
9891008

990-
Handbrake::Handbrake(uint8_t pinAx, uint8_t detectPin)
1009+
Handbrake::Handbrake(PinNum pinAx, PinNum detectPin)
9911010
:
9921011
analogAxis(pinAx),
9931012
detector(detectPin),

src/SimRacing.h

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,18 @@
3131
*/
3232

3333
namespace SimRacing {
34+
/**
35+
* Type alias for pin numbers, using Arduino numbering
36+
*/
37+
using PinNum = int16_t;
38+
39+
/**
40+
* Dummy pin number signaling that a pin is unused
41+
* and can be safely ignored
42+
*/
43+
const PinNum UnusedPin = -1;
44+
45+
3446
/**
3547
* Enumeration for analog axis names, mapped to integers
3648
*/
@@ -63,12 +75,12 @@ namespace SimRacing {
6375
/**
6476
* Class constructor
6577
*
66-
* @param pin the pin number being read. Can be 'NOT_A_PIN' to disable.
78+
* @param pin the pin number being read. Can be 'UnusedPin' to disable.
6779
* @param invert whether the input is inverted, so 'LOW' is detected instead of 'HIGH'
6880
* @param detectTime the amount of time, in ms, the input must be stable for
6981
* before it's interpreted as 'detected'
7082
*/
71-
DeviceConnection(uint8_t pin, bool invert = false, unsigned long detectTime = 250);
83+
DeviceConnection(PinNum pin, bool invert = false, unsigned long detectTime = 250);
7284

7385
/**
7486
* Checks if the pin detects a connection. This polls the input and checks
@@ -108,13 +120,13 @@ namespace SimRacing {
108120
*/
109121
bool readPin() const;
110122

111-
const uint8_t Pin; ///< The pin number being read from. Can be 'NOT_A_PIN' to disable
112-
const bool Inverted; ///< Whether the input is inverted, so 'LOW' is detected instead of 'HIGH'
123+
PinNum pin; ///< The pin number being read from. Can be 'UnusedPin' to disable
124+
bool inverted; ///< Whether the input is inverted, so 'LOW' is detected instead of 'HIGH'
113125
unsigned long stablePeriod; ///< The amount of time the input must be stable for (ms)
114126

115-
ConnectionState state; ///< The current state of the connection
116-
bool pinState; ///< Buffered state of the input pin, accounting for inversion
117-
unsigned long lastChange; ///< Timestamp of the last pin change, in ms (using millis())
127+
ConnectionState state; ///< The current state of the connection
128+
bool pinState; ///< Buffered state of the input pin, accounting for inversion
129+
unsigned long lastChange; ///< Timestamp of the last pin change, in ms (using millis())
118130
};
119131

120132

@@ -129,9 +141,9 @@ namespace SimRacing {
129141
/**
130142
* Class constructor
131143
*
132-
* @param p the I/O pin for this input (Arduino numbering)
144+
* @param pin the I/O pin for this input (Arduino numbering)
133145
*/
134-
AnalogInput(uint8_t p);
146+
AnalogInput(PinNum pin);
135147

136148
/**
137149
* Updates the current value of the axis by polling the ADC
@@ -225,9 +237,9 @@ namespace SimRacing {
225237
void setCalibration(Calibration newCal);
226238

227239
private:
228-
const uint8_t Pin = NOT_A_PIN; ///< the digital pin number for this input
229-
int position; ///< the axis' position in its range, buffered
230-
Calibration cal; ///< the calibration values for the axis
240+
PinNum pin; ///< the digital pin number for this input
241+
int position; ///< the axis' position in its range, buffered
242+
Calibration cal; ///< the calibration values for the axis
231243
};
232244

233245

@@ -285,7 +297,7 @@ namespace SimRacing {
285297
* @param nPedals the number of pedals stored in said data pointer
286298
* @param detectPin the digital pin for device detection (high is detected)
287299
*/
288-
Pedals(AnalogInput* dataPtr, uint8_t nPedals, uint8_t detectPin);
300+
Pedals(AnalogInput* dataPtr, uint8_t nPedals, PinNum detectPin);
289301

290302
/** @copydoc Peripheral::begin() */
291303
virtual void begin();
@@ -381,11 +393,11 @@ namespace SimRacing {
381393
/**
382394
* Class constructor
383395
*
384-
* @param gasPin the analog pin for the gas pedal potentiometer
385-
* @param brakePin the analog pin for the brake pedal potentiometer
386-
* @param detectPin the digital pin for device detection (high is detected)
396+
* @param pinGas the analog pin for the gas pedal potentiometer
397+
* @param pinBrake the analog pin for the brake pedal potentiometer
398+
* @param pinDetect the digital pin for device detection (high is detected)
387399
*/
388-
TwoPedals(uint8_t gasPin, uint8_t brakePin, uint8_t detectPin = NOT_A_PIN);
400+
TwoPedals(PinNum pinGas, PinNum pinBrake, PinNum pinDetect = UnusedPin);
389401

390402
/**
391403
* Sets the calibration data (min/max) for the pedals
@@ -409,12 +421,12 @@ namespace SimRacing {
409421
/**
410422
* Class constructor
411423
*
412-
* @param gasPin the analog pin for the gas pedal potentiometer
413-
* @param brakePin the analog pin for the brake pedal potentiometer
414-
* @param clutchPin the analog pin for the clutch pedal potentiometer
415-
* @param detectPin the digital pin for device detection (high is detected)
424+
* @param pinGas the analog pin for the gas pedal potentiometer
425+
* @param pinBrake the analog pin for the brake pedal potentiometer
426+
* @param pinClutch the analog pin for the clutch pedal potentiometer
427+
* @param pinDetect the digital pin for device detection (high is detected)
416428
*/
417-
ThreePedals(uint8_t gasPin, uint8_t brakePin, uint8_t clutchPin, uint8_t detectPin = NOT_A_PIN);
429+
ThreePedals(PinNum pinGas, PinNum pinBrake, PinNum pinClutch, PinNum pinDetect = UnusedPin);
418430

419431
/**
420432
* Sets the calibration data (min/max) for the pedals
@@ -540,9 +552,9 @@ namespace SimRacing {
540552
* @param pinX the analog input pin for the X axis
541553
* @param pinY the analog input pin for the Y axis
542554
* @param pinRev the digital input pin for the 'reverse' button
543-
* @param detectPin the digital pin for device detection (high is detected)
555+
* @param pinDetect the digital pin for device detection (high is detected)
544556
*/
545-
AnalogShifter(uint8_t pinX, uint8_t pinY, uint8_t pinRev = NOT_A_PIN, uint8_t detectPin = NOT_A_PIN);
557+
AnalogShifter(PinNum pinX, PinNum pinY, PinNum pinRev = UnusedPin, PinNum pinDetect = UnusedPin);
546558

547559
/**
548560
* Initializes the hardware pins for reading the gear states.
@@ -663,7 +675,7 @@ namespace SimRacing {
663675
} calibration;
664676

665677
AnalogInput analogAxis[2]; ///< Axis data for X and Y
666-
const uint8_t PinReverse; ///< The pin for the reverse gear button
678+
PinNum pinReverse; ///< The pin for the reverse gear button
667679
DeviceConnection detector; ///< detector instance for checking if the shifter is connected
668680
};
669681

@@ -679,9 +691,9 @@ namespace SimRacing {
679691
* Class constructor
680692
*
681693
* @param pinAx analog pin number for the handbrake axis
682-
* @param detectPin the digital pin for device detection (high is detected)
694+
* @param pinDetect the digital pin for device detection (high is detected)
683695
*/
684-
Handbrake(uint8_t pinAx, uint8_t detectPin = NOT_A_PIN);
696+
Handbrake(PinNum pinAx, PinNum pinDetect = UnusedPin);
685697

686698
/**
687699
* Initializes the pin for reading from the handbrake.
@@ -748,7 +760,7 @@ namespace SimRacing {
748760
class LogitechPedals : public ThreePedals {
749761
public:
750762
/** @copydoc ThreePedals::ThreePedals */
751-
LogitechPedals(uint8_t gasPin, uint8_t brakePin, uint8_t clutchPin, uint8_t detectPin = NOT_A_PIN);
763+
LogitechPedals(PinNum pinGas, PinNum pinBrake, PinNum pinClutch, PinNum pinDetect = UnusedPin);
752764
};
753765

754766
/**
@@ -763,7 +775,7 @@ namespace SimRacing {
763775
class LogitechDrivingForceGT_Pedals : public TwoPedals {
764776
public:
765777
/** @copydoc TwoPedals::TwoPedals */
766-
LogitechDrivingForceGT_Pedals(uint8_t gasPin, uint8_t brakePin, uint8_t detectPin = NOT_A_PIN);
778+
LogitechDrivingForceGT_Pedals(PinNum pinGas, PinNum pinBrake, PinNum pinDetect = UnusedPin);
767779
};
768780

769781
/**
@@ -775,7 +787,7 @@ namespace SimRacing {
775787
class LogitechShifter : public AnalogShifter {
776788
public:
777789
/** @copydoc AnalogShifter::AnalogShifter */
778-
LogitechShifter(uint8_t pinX, uint8_t pinY, uint8_t pinRev = NOT_A_PIN, uint8_t detectPin = NOT_A_PIN);
790+
LogitechShifter(PinNum pinX, PinNum pinY, PinNum pinRev = UnusedPin, PinNum pinDetect = UnusedPin);
779791
};
780792

781793

0 commit comments

Comments
 (0)