April 18, 2026
Description
If there is enough interest, I will also release a full DIY Sequential Shifter design in the future.
The firmware already supports both the handbrake and the shifter.
This is a DIY analog sim racing handbrake designed for PC racing games like rally simulators and track racing titles.
It uses an ESP32-S3 with native USB to act as a plug-and-play HID device — no external Arduino or USB converter needed.
The design is compact, strong, and fully 3D printable, using mostly standard hardware components.
The handbrake works analog, meaning the position directly affects braking force — just like a real hydraulic handbrake.
Included in this project:
(All parts are included in the STL files)
For the best surface quality, I used PLA/PETG support interface filament.
This gives a much cleaner finish on supported surfaces compared to standard supports.
Recommended materials:
Stronger materials are always possible if you want extra rigidity or long-term durability.
The handbrake uses a linear sliding mechanism:
Important:
The potentiometer has 3 pins:
⚠️ Use 3.3V only, not 5V
The firmware reads this signal and converts it into a USB axis.
You can use:
Open:
joy.cpl
Optional:
In games like:
Simply:
If there is enough interest, I will release:
👉 A full DIY Sequential Shifter (mechanical design) to match this handbrake
This project is designed to give you a realistic sim racing experience with minimal cost and maximum customization.
Build it, tweak it, improve it — and enjoy rallying the way it should be. 🏁
🔧 Firmware (Arduino / ESP32-S3)
#include "USB.h"
#include "USBHID.h"
USBHID HID;
const int handbrakePin = 2;
const int upShiftPin = 6;
const int downShiftPin = 7;
// HID report buffer: 1 byte knoppen, 1 byte X, 1 byte Y
uint8_t report[3];
void setup() {
Serial.begin(115200);
pinMode(handbrakePin, INPUT);
pinMode(upShiftPin, INPUT_PULLUP);
pinMode(downShiftPin, INPUT_PULLUP);
HID.begin();
USB.begin();
Serial.println("ESP32-S3 USB HID Gamepad gestart!");
}
void loop() {
// Handrem uitlezen
int rawHandbrake = analogRead(handbrakePin); // 0–4095
int8_t mappedHandbrake = map(rawHandbrake, 0, 4095, -127, 127);
// Knoppen uitlezen
bool upShift = (digitalRead(upShiftPin) == LOW);
bool downShift = (digitalRead(downShiftPin) == LOW);
report[0] = 0;
if (upShift) report[0] |= 1;
if (downShift) report[0] |= 2;
report[1] = mappedHandbrake;
report[2] = 0;
// HID report sturen (report ID = 1)
HID.SendReport(1, report, sizeof(report));
delay(10);
}
License:
MakerWorld Exclusive License