Skip to content

Commit c12c059

Browse files
authored
Merge pull request #2 from dmadison/handbrake
Add Handbrake Support
2 parents 21db3c6 + dda95c1 commit c12c059

File tree

8 files changed

+328
-15
lines changed

8 files changed

+328
-15
lines changed

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,15 @@ Run one of the library examples in the Arduino IDE by going to `File -> Examples
1414

1515
## Supported Devices
1616

17-
* [Logitech Three Pedal Peripheral (Gas, Brake, Clutch)](http://dmadison.github.io/Sim-Racing-Arduino/docs/logitech_pedals.html)
17+
### Generic Devices
18+
* [Two pedal peripherals (gas + brake)](https://dmadison.github.io/Sim-Racing-Arduino/docs/class_sim_racing_1_1_two_pedals.html)
19+
* [Three pedal peripherals (gas, brake, clutch)](https://dmadison.github.io/Sim-Racing-Arduino/docs/class_sim_racing_1_1_three_pedals.html)
20+
* [Analog shifters](https://dmadison.github.io/Sim-Racing-Arduino/docs/class_sim_racing_1_1_analog_shifter.html)
21+
* [Analog handbrakes](https://dmadison.github.io/Sim-Racing-Arduino/docs/class_sim_racing_1_1_handbrake.html)
22+
23+
### Commercial Devices
1824
* [Logitech Two Pedal Peripheral (Gas, Brake)](http://dmadison.github.io/Sim-Racing-Arduino/docs/logitech_pedals.html)
25+
* [Logitech Three Pedal Peripheral (Gas, Brake, Clutch)](http://dmadison.github.io/Sim-Racing-Arduino/docs/logitech_pedals.html)
1926
* [Logitech Driving Force Shifter](http://dmadison.github.io/Sim-Racing-Arduino/docs/logitech_shifter.html)
2027

2128
## License

docs/pages/supported_devices.md

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,13 @@
11
# Supported Devices
22

3-
### Commercial Devices:
4-
5-
- @subpage logitech_pedals
6-
- @subpage logitech_shifter
7-
83
### Generic Devices
94

10-
#### Pedals
5+
* Two pedal peripherals (gas + brake) using `SimRacing::TwoPedals`
6+
* Three pedal peripherals (gas, brake, clutch) using `SimRacing::ThreePedals`
7+
* Analog shifters using `SimRacing::AnalogShifter`
8+
* Analog handbrakes using `SimRacing::Handbrake`
119

12-
The library supports generic pedal devices that connect via the microcontroller's analog to digital converter (ADC).
10+
### Commercial Devices
1311

14-
* Two pedal setups (gas + brake) use the `SimRacing::TwoPedals` class.
15-
* Three pedal setups (gas, brake, clutch) use the `SimRacing::ThreePedals` class.
16-
17-
#### Shifters
18-
19-
The library supports generic shifting devices that record gear position using a pair of potentiometers. These are supported as part of the `SimRacing::AnalogShifter` class.
12+
- @subpage logitech_pedals
13+
- @subpage logitech_shifter
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Project Sim Racing Library for Arduino
3+
* @author David Madison
4+
* @link github.com/dmadison/Sim-Racing-Arduino
5+
* @license LGPLv3 - Copyright (c) 2022 David Madison
6+
*
7+
* This file is part of the Sim Racing Library for Arduino.
8+
*
9+
* This program is free software: you can redistribute it and/or modify
10+
* it under the terms of the GNU Lesser General Public License as published by
11+
* the Free Software Foundation, either version 3 of the License, or
12+
* (at your option) any later version.
13+
*
14+
* This program is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* GNU Lesser General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU Lesser General Public License
20+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
21+
*/
22+
23+
/**
24+
* @brief Emulates the handbrake as a joystick over USB.
25+
* @example HandbrakeJoystick.ino
26+
*/
27+
28+
// This example requires the Arduino Joystick Library
29+
// Download Here: https://github.com/MHeironimus/ArduinoJoystickLibrary
30+
31+
#include <SimRacing.h>
32+
#include <Joystick.h>
33+
34+
const int Pin_Handbrake = A2;
35+
36+
SimRacing::Handbrake handbrake(Pin_Handbrake);
37+
38+
Joystick_ Joystick(
39+
JOYSTICK_DEFAULT_REPORT_ID, // default report (no additional pages)
40+
JOYSTICK_TYPE_JOYSTICK, // so that this shows up in Windows joystick manager
41+
0, // number of buttons (none)
42+
0, // number of hat switches (none)
43+
false, false, // no X and Y axes
44+
true, // include Z axis for the handbrake
45+
false, false, false, false, false, false, false, false); // no other axes
46+
47+
const int ADC_Max = 1023; // max value of the analog inputs, 10-bit on AVR boards
48+
49+
50+
void setup() {
51+
handbrake.begin(); // initialize handbrake pins
52+
53+
// if you have one, your calibration line should go here
54+
55+
Joystick.begin(false); // 'false' to disable auto-send
56+
57+
Joystick.setZAxisRange(0, ADC_Max);
58+
}
59+
60+
void loop() {
61+
handbrake.update();
62+
63+
int pos = handbrake.getPosition(0, ADC_Max);
64+
Joystick.setZAxis(pos);
65+
66+
Joystick.sendState();
67+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Project Sim Racing Library for Arduino
3+
* @author David Madison
4+
* @link github.com/dmadison/Sim-Racing-Arduino
5+
* @license LGPLv3 - Copyright (c) 2022 David Madison
6+
*
7+
* This file is part of the Sim Racing Library for Arduino.
8+
*
9+
* This program is free software: you can redistribute it and/or modify
10+
* it under the terms of the GNU Lesser General Public License as published by
11+
* the Free Software Foundation, either version 3 of the License, or
12+
* (at your option) any later version.
13+
*
14+
* This program is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* GNU Lesser General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU Lesser General Public License
20+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
21+
*/
22+
23+
/**
24+
* @brief Prints handbrake position percentage over Serial.
25+
* @example HandbrakePrint.ino
26+
*/
27+
28+
#include <SimRacing.h>
29+
30+
const int Pin_Handbrake = A2;
31+
32+
SimRacing::Handbrake handbrake(Pin_Handbrake);
33+
34+
35+
void setup() {
36+
handbrake.begin(); // initialize handbrake pins
37+
38+
// if you have one, your calibration line should go here
39+
40+
Serial.begin(115200);
41+
while (!Serial); // wait for connection to open
42+
43+
Serial.println("Starting...");
44+
}
45+
46+
void loop() {
47+
// send some serial data to run conversational calibration
48+
if (Serial.read() != -1) {
49+
handbrake.serialCalibration();
50+
delay(2000);
51+
}
52+
53+
handbrake.update();
54+
55+
Serial.print("Handbrake: ");
56+
57+
int pos = handbrake.getPosition();
58+
Serial.print(pos);
59+
Serial.print("%");
60+
Serial.println();
61+
62+
delay(100);
63+
}

keywords.txt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ AnalogShifter KEYWORD1
3535

3636
LogitechShifter KEYWORD1
3737

38+
# Handbrake Classes
39+
Handbrake KEYWORD1
40+
3841
#######################################
3942
# Peripheral Class Methods and Functions (KEYWORD2)
4043
#######################################
@@ -65,6 +68,9 @@ setCalibration KEYWORD2
6568
# Pedal Methods and Functions (KEYWORD2)
6669
#######################################
6770

71+
getPosition KEYWORD2
72+
getPositionRaw KEYWORD2
73+
6874
hasPedal KEYWORD2
6975

7076
getNumPedals KEYWORD2
@@ -84,11 +90,24 @@ gearChanged KEYWORD2
8490
getGearMin KEYWORD2
8591
getGearMax KEYWORD2
8692

93+
getPosition KEYWORD2
94+
getPositionRaw KEYWORD2
95+
8796
getReverseButton KEYWORD2
8897

8998
setCalibration KEYWORD2
9099
serialCalibration KEYWORD2
91100

101+
#######################################
102+
# Handbrake Methods and Functions (KEYWORD2)
103+
#######################################
104+
105+
getPosition KEYWORD2
106+
getPositionRaw KEYWORD2
107+
108+
setCalibration KEYWORD2
109+
serialCalibration KEYWORD2
110+
92111
#######################################
93112
# Instances (KEYWORD2)
94113
#######################################

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name=Sim Racing Library
22
version=1.0.0
33
author=David Madison
44
maintainer=David Madison
5-
sentence=Interface with sim racing peripherals including pedals and gear shifters.
5+
sentence=Interface with sim racing peripherals including pedals, gear shifters, and handbrakes.
66
paragraph=Works out of the box with the Logitech pedals and Logitech Driving Force gear shifter. Supports easy USB joystick output.
77
category=Signal Input/Output
88
url=https://github.com/dmadison/Sim-Racing-Arduino

src/SimRacing.cpp

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -902,4 +902,106 @@ LogitechShifter::LogitechShifter(uint8_t pinX, uint8_t pinY, uint8_t pinRev, uin
902902
this->setCalibration({ 490, 440 }, { 253, 799 }, { 262, 86 }, { 460, 826 }, { 470, 76 }, { 664, 841 }, { 677, 77 }, 0.70, 0.50, 0.70);
903903
}
904904

905+
//#########################################################
906+
// Handbrake #
907+
//#########################################################
908+
909+
Handbrake::Handbrake(uint8_t pinAx, uint8_t detectPin)
910+
: analogAxis(pinAx), detector(detectPin)
911+
{}
912+
913+
void Handbrake::begin() {
914+
update(); // set initial handbrake position
915+
}
916+
917+
bool Handbrake::update() {
918+
bool changed = false;
919+
920+
detector.poll();
921+
if (detector.getState() == DeviceConnection::Connected) {
922+
changed = analogAxis.read();
923+
}
924+
else if (detector.getState() == DeviceConnection::Unplug) {
925+
analogAxis.setPosition(analogAxis.getMin());
926+
}
927+
928+
return changed;
929+
}
930+
931+
long Handbrake::getPosition(long rMin, long rMax) const {
932+
return analogAxis.getPosition(rMin, rMax);
933+
}
934+
935+
int Handbrake::getPositionRaw() const {
936+
return analogAxis.getPositionRaw();
937+
}
938+
939+
void Handbrake::setCalibration(AnalogInput::Calibration newCal) {
940+
analogAxis.setCalibration(newCal);
941+
analogAxis.setPosition(analogAxis.getMin()); // reset to min
942+
}
943+
944+
void Handbrake::serialCalibration(Stream& iface) {
945+
if (isConnected() == false) {
946+
iface.print(F("Error! Cannot perform calibration, "));
947+
iface.print(F("handbrake"));
948+
iface.println(F(" is not connected."));
949+
return;
950+
}
951+
952+
const char* separator = "------------------------------------";
953+
954+
iface.println();
955+
iface.println(F("Sim Racing Library Handbrake Calibration"));
956+
iface.println(separator);
957+
iface.println();
958+
959+
AnalogInput::Calibration newCal;
960+
961+
// read minimum
962+
iface.println(F("Keep your hand off of the handbrake to record its resting position"));
963+
iface.println(F("Send any character to continue."));
964+
waitClient(iface);
965+
966+
analogAxis.read();
967+
newCal.min = analogAxis.getPositionRaw();
968+
iface.println();
969+
970+
// read maximum
971+
iface.println(F("Now pull on the handbrake and hold it at the end of its range"));
972+
iface.println(F("Send any character to continue."));
973+
waitClient(iface);
974+
975+
analogAxis.read();
976+
newCal.max = analogAxis.getPositionRaw();
977+
iface.println();
978+
979+
// set new calibration
980+
this->setCalibration(newCal);
981+
982+
// print finished calibration
983+
iface.println(F("Here is your calibration:"));
984+
iface.println(separator);
985+
iface.println();
986+
987+
iface.print(F("handbrake.setCalibration("));
988+
iface.print('{');
989+
iface.print(newCal.min);
990+
iface.print(F(", "));
991+
iface.print(newCal.max);
992+
iface.print("});");
993+
iface.println();
994+
995+
iface.println();
996+
iface.println(separator);
997+
iface.println();
998+
999+
iface.print(F("Paste this line into the setup() function. The "));
1000+
iface.print(F("handbrake"));
1001+
iface.print(F(" will be calibrated with these values on startup."));
1002+
iface.println(F("\nCalibration complete! :)\n\n"));
1003+
1004+
flushClient(iface);
1005+
}
1006+
9051007
}; // end SimRacing namespace

0 commit comments

Comments
 (0)