Overview
A comprehensive guide to making your own H-shifter!
Foreword
First of all, many ideas used in this guide are from Bobradars steam guide here:
[link]
And hackaday-forum thread here:
[link]
Thanks to both these sources for inspiration and guidance!
DISCLAIMER: IF YOU BREAK YOUR PC IT’S YOUR FAULT FOR PROBABLY MAKING A SHORT CIRCUIT WHEN SOLDERING.
The build
Now, onto the guide itself!
What I’ve built here is a 7+R shifter with a handbrake lever and a clutch pedal.
You’ll need these items for your setup, but this is just a rough guideline, and you’re free to use whatever you have at your disposal.
- Basic handyman skills and tools or someone who has them
- Various building materials, plywood, chipboard, plastic, sheet metal, aluminium rods etc.
- Cabinet clamps
- Potentiometers, microswitches and wires
- Spare time
Now the basic outline is that you’ll need to build this long baseplate with two vertical supports and have the shifter gate on top of those supports, with a kind of a rocking system underneath.
Kind of like this, but with more finesse.
Of course you are free to use whatever is at your disposal. There we have an aluminium rod that is 11 millimeters thick, and has a 10mm thread for the knob.. well, threaded on the end of it. There is a spring that is sligthly smaller in diameter in the bottom, attached to the baseplate with a washer and a screw. That aluminium rod is then forced through the spring. This gives us that familiar neutral feel we have on a car gearbox. The shifter stays in gear with the two cabinet door clamps that are attached to the middle rocker and the gearstick., the correct positioning depends on the shifter gates size.
“What size components do you have?”, I hear you ask, well…
I didn’t have any measurements as I pretty much eyeballed it throughout the build, but the base made from chipboard is 46cm long, 11cm wide and 1,5cm thick. The whole structure is 13cm tall, while the shifter plate is 11cm wide, 22cm long and 1cm thick plywood. The shifter gate itself is 8cm wide and 9cm long, and the gaps range from 12mm in the middle to 15mm on the leftmost and rightmost gap with about 1cm between each gap. Grid paper is very useful when making the drawings to get the measurements right. The rocking system is 13cm long and 4cm wide and it’s 6cm above the base.
Now to the handbrake: The lever is an aluminium tube that’s been flattened on one end and had a 6mm hole drilled through it. It is attached to the aluminium angled plate with a 10 kilo-ohm potentiometer or a variable resistor that has a 6 mm thread threaded on the actuator, or the small shaft in the middle that changes the resistance. The return spring is attached to the lever by drilling a small hole that has the end of the spring run through it with the other end screwed into the end of the baseplate.
So the end result should be something like this:
“But wait, what about the clutch?” Glad you asked.
What I got was an old pedal from an electronic sewing machine that I disassembled, and installed a sliding variable 50 kilo-ohm resistor and utilised the old lever actuators for it. I installed a new breadboard in the pedal housing and soldered the wires into it and changed the cable from the old 2-wire one to a 4-wire. Here’s one I prepared earlier:
So, time to solder on!
The electric bits
Now, you can’t just put in some wires and plug it into your PC. Luckily, the guys at Arduino or PJRC have us covered. What I’ve been using is a chinese copy of an Arduino Micro, they cost a lot less than the official ones and lack some pins but should be good enough for our purposes. They can usually be found on Ebay for a few bucks. What we also have is 8, 9 or 10 microswitches depending on the build, if you have an analog clutch or handbrake you need 9 microswitches and 8 if you have both. You might be asking “What is a microswitch?” Good question, glad you asked!
Now this is a microswitch. It’s basically a spring loaded mechanism that turns that small lever in the middle connected from 0 to NC into a connected state when enough pressure is applied. What we want to do is to have our switches mounted on the underside of the shifter gate and make sure the gearstick hits the lever with enough pressure to establish a connection. The gearstick is held in gear with the small cabinet clamps attached to the rocker and the gearstick, more of that later.
So we want a wire going from each digital output pin from 0 to 7 (Or 8 or 9, the pin numbering starts from 0) into the connected pin on the switch and the the ground pin can be connected to the ground via just one wire run from each of the switches ground pins. The potentiometers are a bit more tricky. They also have 3 pins or in some cases more. The circular ones have the variable output pin in the middle, so we want that to be connected to the analog input pin to A0 and the other pins to ground and +5 Volts. The circuitboard should have a pin tha puts out 5 volts, but if it doesn’t you can just put another digital output pin to HIGH and have 5 volts in that. Well talk about that later. Usually the pins can be figured out by using a digital multimeter by checking the resistance between two pins and turning or sliding the actuator. If the resistance stays the same, you have the measuring cables on ground and input wires. If the resistance changes, you have the cables on ground OR input, and output.
Here is an example schematic on the board connections:
The red dots are junctions, if lines cross and there is no red dot they are not connected to each other.
You might be wondering what is the handbrake mode switch. Well that changes the handbrake from an analog axis to a button. The code will show how.
The code
Now, my build utilizes a library that makes the Arduino appear as a joystick, but beware AND THIS IS IMPORTANT! You absolutely NEED to have a circuitboard, Arduino or a PJRC Teensy, that has the atmega32u4 microcontroller in it, because atmega32u4 has native USB support. The information is easy enough to find on the manufacturers website. The library can be found here: [link]
However, the Teensy does NOT need the library.
Why did I decide to use this library instead of using the Keyboard method in bobradars guide? Well, with this library you can use analog inputs and it doesn’t spam numbers into any chat window or notepad or whatever if you happen to “be in gear” and alt+tab.
The program used to write the code and upload it into the circuitboard of your choice can be downloaded from arduino.cc and it works with both the Teensy and Arduino boards. The library has to be installed to the arduinos library folder, the default is C:Program Files (x86)Arduinolibraries
The code below has comments and edits dependent on if you’re using Teensy or not. Teensy code comes from Fleethammer.
On to the code itself:
#include “Joystick.h” //This is NOT required if using Teensy.
int gearR = 0; // Reverse gear set to pin 0
int gear1 = 1; //All pin numbers are to personal preference and whatever suits the build best
int gear2 = 2;
int gear3 = 3;
int gear4 = 4;
int gear5 = 5;
int gear6 = 6;
int gear7 = 7;
void setup() {
pinMode(gearR, OUTPUT); // Set the gear as an input
digitalWrite(gearR, HIGH); //Set the pin to HIGH or +5 Volts
pinMode(gear1, OUTPUT);
digitalWrite(gear1, HIGH);
pinMode(gear2, OUTPUT);
digitalWrite(gear2, HIGH);
pinMode(gear3, OUTPUT);
digitalWrite(gear3, HIGH);
pinMode(gear4, OUTPUT);
digitalWrite(gear4, HIGH);
pinMode(gear5, OUTPUT);
digitalWrite(gear5, HIGH);
pinMode(gear6, OUTPUT);
digitalWrite(gear6, HIGH);
pinMode(gear7, OUTPUT);
digitalWrite(gear7, HIGH);
pinMode(A3, INPUT);
pinMode(A0, INPUT);
pinMode(8, OUTPUT);
pinMode(10, OUTPUT);
pinMode(14, OUTPUT);
pinMode(16, OUTPUT);
digitalWrite(8, HIGH);
digitalWrite(10, HIGH);
digitalWrite(14, HIGH); //These are required if your chipset
digitalWrite(16, HIGH); //Doesn’t have a +5V output pin
Joystick.begin(); //Not needed with Teensy
}
void loop() {
if (digitalRead(gearR) == 0) // gear engaged (the ‘0’ means the pin has been shorted to the ground, causing a drop in voltage on that pin)
{
Joystick.setButton(0, 1); //Button number 0 is set to 1 or active state, Arduino
//Joystick.button(0, 1); //Button number 0 is set to 1 or active state, Teensy
}
if (digitalRead(gearR) == 1) //gear disengaged (the ‘1’ means the pin is no longer shorted to the ground, which increases voltage on that pin)
{
Joystick.setButton(0, 0); //tells the PC to let go of the key (otherwise, it would continue to hold it forever, even after another gear is selected)
//Joystick.button(0, 0); //Button number 0 is set to 0 or inactive state, Teensy
}
if (digitalRead(gear1) == 0)
{
Joystick.setButton(1, 1);
}
if (digitalRead(gear1) == 1) //gear disengaged
{
Joystick.setButton(1, 0);
}
if (digitalRead(gear2) == 0)
{
Joystick.setButton(2, 1);
}
if (digitalRead(gear2) == 1) //gear disengaged
{
Joystick.setButton(2, 0);
}
if (digitalRead(gear3) == 0)
{
Joystick.setButton(3, 1);
}
if (digitalRead(gear3) == 1) //gear disengaged
{
Joystick.setButton(3, 0);
}
if (digitalRead(gear4) == 0)
{
Joystick.setButton(4, 1);
}
if (digitalRead(gear4) == 1) //gear disengaged
{
Joystick.setButton(4, 0);
}
if (digitalRead(gear5) == 0)
{
Joystick.setButton(5, 1);
}
if (digitalRead(gear5) == 1) //gear disengaged
{
Joystick.setButton(5, 0);
}
if (digitalRead(gear6) == 0)
{
Joystick.setButton(6, 1);
}
if (digitalRead(gear6) == 1) //gear disengaged
{
Joystick.setButton(6, 0);
}
if (digitalRead(gear7) == 0)
{
Joystick.setButton(7, 1);
}
if (digitalRead(gear7) == 1) //gear disengaged
{
Joystick.setButton(7, 0);
}
// if (digitalRead(handBrake) == 0) //handbrake engaged //Use these if you have a digital handbrake
// {
// Joystick.setButton(8, 1);
// }
/*if (digitalRead(handBrake) == 1) //handbrake disengaged //Use these if you have a digital handbrake
{
Joystick.setButton(8, 0);
}*/
if (digitalRead(10)==0) //This checks the state of the handbrake mode switch, this is analog //mode
{
//Serial.print(“Handbrake raw: “); //These three lines
//Serial.print(analogRead(A0)); //are used
//Serial.print(“t”); //for debugging
if (analogRead(A0)>=1019)
{
Joystick.setThrottle(0);
//Joystick.X(0)); //Teensy analog axis X
}
if (analogRead(A0)<1019)
{
int HBval = (-2.125*analogRead(A0))+2150; //This is unique to your build and you’ll have to calculate it yourself
if (HBval < 0) HBval = 0;
if (HBval > 255) HBval = 255;
Joystick.setThrottle(HBval);
//Joystick.X(analogRead(A0)); //Teensy analog axis X
// Serial.print(“Handbrake: “); //Debug
//Serial.println(HBval); //lines
}
}
if (digitalRead(8)==0)//This checks the state of the handbrake mode switch, this is digital mode
{
if (analogRead(A0)>=1019)
{
Joystick.setThrottle(0);
Joystick.setButton(8, 0);
}
if (analogRead(A0)<900)
{
Joystick.setButton(8, 1);
}
}
if (analogRead(A3)>=1019)
{
Joystick.setRudder(0);
//Joystick.Y(analogRead(A0)); //Teensy analog axis Y
}
if (analogRead(A3)<1019)
{
//Serial.print(“Clutch raw: “);
// Serial.print(analogRead(A3));
// Serial.print(“t”);
int Cval = -0.3706395349*analogRead(A3)+344.3386628; //This is unique to your build and you’ll have to calculate it yourself
//Serial.print(“Clutch: “);
if (Cval < 0) Cval = 0;
if (Cval > 255) Cval = 255;
//Serial.println(Cval);
Joystick.setRudder(Cval);
//Joystick.Y(analogRead(A0)); //Teensy analog axis Y
}
}
Now, about the things you have to calculate yourself. When you have the build done, you have to set the limits of your analogue axis. You do that by removing the commented sections that have Serial.print in them. Then you open up the serial monitor in the arduino and see what data is printed. tha different axis go from 0 to 255, and the formula is as follows:
y = k*x+b, where y is the axis value, k is the multiplier assigned to x which is the analogue input that varies from 0 to 1023 and b is the offset. So in this case the angle where the handbrake is not in use has 1019 coming in in the input (x), so we multiply it by -1.1643835616438356164383561643836(k, doesn’t need to be this accurate) and add 1185.50684931506849315068493 which should give us 0 as y value or HBval, meaning the handbrake is off. When the lever is pulled, the input goes smaller, while the offset stays the same, so output goes higher.
Teensy has it a bit easier, since axis values on Teensy go from 0 to 1023 so you can use the analog input as is and no calculations need to be made.
TL;DR – VIDEO GUIDES
Now here we go, video guides on the different aspects of the build.
“Wait a minute, this still has a digital hand brake and no clutch!” Yes, yes, yes, keep your pants on.
In action:
Final thoughts
The shifter works quite well, but if I were to do it again, there are some things I would do differently: Thinner shifter gate material, 1cm plywood is unnecessarily thick, I’d switch that to 1-2mm thick steel and polish it, but making the cuts precisely is too hard without a proper laser cutter. Another choice would be to use a 3D printer. The microswitches are also slightly too big.