Simracing 2DOF – DIY
Construction d’un simulateur dynamique avec des moteurs d’essuie-glace de camion
Simulateur 2DOF – ESP32 + BTS7960 + AS5600 + SimTools v3
English
Supplies
Cout :
-Moteurs :100€ ici smolka 120w mais des moteurs de fauteuil roulant 250w 75 rpm serais mieux.
-ESP32 : 5€
-AS5600 : 5€
-Drivers : 20€ Motomonster BTS7960 (j’en ai cramé 3 !) ou sabertooth 2x32 135€ (mais bien meilleur, il faudra adapter le code)
-Alimentation : 60€
-Siege Baquet : 180€
-Bois ferraille visserie : 200€
-Volant Logetch g29 : 230€
-Ceinture 4 points : 38€
-manette simulateur de vol : 80€
-
Total : 920€ mais avec de la récup et des dons il m’a couté 480€, merci Patrice pour le volant, merci Nico pour ventilot/alim et merci la communauté qui m’a aidé pour les aspect technique… et pour être honnête un peu d’IA pour la partie programmation.
English
Cost:
-Motors: €100 here (Smolka 120W), but 250W 75 RPM wheelchair motors would be better.
-ESP32: €5
-AS5600: €5
-Drivers: €20 Motomonster BTS7960 (I burned through 3 of them!) or Sabertooth 2x32 €135 (but much better, the code will need to be adapted)
-Power supply: €60
-Bucket seat: €180
-Wood, metal, screws: €200
-Logetch G29 steering wheel: €230
-4-point harness: €38
-Flight simulator controller: €80
- Total: €920, but with salvaged parts and donations, it cost me €480. Thanks Patrice for the steering wheel, thanks Nico for the fan/power supply, and thanks to the community that helped me with the technical aspects… and to be honest, a little AI for the programming.
2️⃣ ÉLECTRONIQUE (BRANCHEMENTS) 2️⃣ ELECTRONICS (CONNECTIONS)
Matériel
-2 moteurs essuie-glace de camion 120w (ici smolka) mais des moteurs de fauteuil roulant de 250w serait encore mieux
-2 AS5600 capteur angulaire magnétique utilisé avec le bus I2C (attention les AS5600 ont des adresses fix que l’on ne peut pas changer, il faut donc avoir 2 bus i2c, les EPS32 ont plusieurs bus mais les arduino uno qu’un seul)
-2 drivers de puissance moto Monster BTS7960 capable de fournir jusqu’à 43A sous 24v (très sensible au défaut de masse, j’’en ai cramé 3 dans mes tests, la sabertooth 2x32 est un meilleur choix (plus cher) mais il faudra adapter le code du microcontrôleur.
- un ESP32
-une alimentation 24v 50A 1000w (ou 2 de 12v mis en série)
🔋 Alimentation
Élément
Tension
ESP32
5 V (Vin ou USB)
AS5600
3 V
BTS7960 logique
3 V
BTS7960 moteur
24 V (séparé)
ALIM 24V
+24V ────────────────┬──────── BTS7960 #1 B+
└──────── BTS7960 #2 B+
GND ────────────────┬──────── BTS7960 #1 B-
├──────── BTS7960 #2 B-
└──────── GND ESP32
⚠️ MASSE COMMUNE OBLIGATOIRE
🔌 BTS7960 (par moteur)
BTS7960 ESP32
RPWM RPWMx
LPWM LPWMx
R_EN RENx
L_EN LENx
GND GND
VCC 5 V
Sortie moteur → moteur essuie-glace
🧭 AS5600
AS5600 ESP32
VCC 3 V
GND GND
SDA SDAx
SCL SCLx
Aimant centré sur l’axe moteur ⚠️
Distance typique entre l’aimant et l’AS5600: 1–2 mm
Un support a été fait via une imprimante 3D pour l’AS5600 avec d’un côté l’aimant relié à l’axe du moteur et de l’autre le capteur AS5600. Le support pourra se tourner manuellement pour régler le centre du simulateur.
Banc de test avec une planche à pain (attention aux masses du driver BTS7960, c’est très sensible et risque de cramer le driver si pas présente)
Patte thermique à mettre sur les drivers car pas présent
Montage au propre des composants électronique avec des nappes
Mise en place de 2 alimentations 12v en série de serveur pour avoir du 24v, si vous utilisez ce genre d’alim il faut souder un fil entre 2 pattes pour que l’alim démarre (cela dépend de l’alimentation)
On range tout le monde ensemble et mise en place d’un ventilateur au-dessus des drivers pour extraire la chaleur avec un disjoncteur pour pouvoir couper la puissance, il manque encore des fusibles à mettre sur les alimentations des drivers et un coup de point d’arrêt d’urgence.
English
Materials
- 2 x 120W truck wiper motors (here, Smolka), but 250W wheelchair motors would be even better.
- 2 x AS5600 magnetic angle sensors used with the I2C bus (note that AS5600s have fixed addresses that cannot be changed, so you need two I2C buses. EPS32s have multiple buses, but Arduino Unos only have one.)
- 2 x Monster BTS7960 motorcycle power drivers capable of supplying up to 43A at 24V (very sensitive to ground faults; I burned out three in my tests. The Sabertooth 2x32 is a better choice (more expensive), but you'll need to adapt the microcontroller code.)
- One ESP32
- One 24V 50A 1000W power supply (or two 12V power supplies connected in series)
🔋 Power Supply
Component
Voltage ESP32
5V (Vin or USB)
AS5600
3V
BTS7960 Logic
3V
BTS7960 Motor
24V (Separate)
24V Power Supply
+24V ───────────────┬──────── BTS7960 #1 B+
└──────── BTS7960 #2 B+
GND ────────────────┬──────── BTS7960 #1 B-
├──────── BTS7960 #2 B-
└──────── GND ESP32
🔌 BTS7960 (per motor)
BTS7960 ESP32
RPWM RPWMx
LPWM LPWMx
R_EN RENx
L_EN LENx
GND GND
VCC 5 V
Motor output → wiper motor
🧭 AS5600
AS5600 ESP32
VCC 3 V
GND GND
SDA SDAx
SCL SCLx
Magnet centered on the motor shaft ⚠️
Typical distance between the magnet and the AS5600: 1–2 mm
A mount was created using a 3D printer for the AS5600, with the magnet connected to the motor shaft on one side and the AS5600 sensor on the other. The mount can be manually rotated to center the simulator.
Test bench with a breadboard (be careful with the BTS7960 driver's ground connections; they are very sensitive and could damage the driver if not present).
Thermal paste needs to be applied to the drivers as it is not included.
Cleanly assemble the electronic components with ribbon cables.
Install two 12V server power supplies in series to obtain 24V. If you use this type of power supply, you will need to solder a wire between two pins for it to start (this depends on the power supply).
Put everything together and install a fan above the drivers to exhaust the heat, along with a circuit breaker to cut the power. Fuses still need to be installed on the driver power supplies, and an emergency stop switch is required.
3️⃣ PROGRAMMATION (EXPLICATION DU CODE) 3️⃣ PROGRAMMING (EXPLANATION OF THE CODE)
Attention, j’ai moi-même développé le firmware pour le microcontrôleur esp32, cela fonctionne bien pour moi mais je ne peux pas garantir qu’il n’y ai pas de bug / amélioration a faire.
La programmation s’effectue via l’IDE de l’arduino, bien sélectionner la carte esp32 et le bon port com, explication du programme injecté dans l’ESP32 (attention, j’ai fait le code mais je ne garantit pas qu’il n’y ai pas de bug…) :
📚 Librairies
#include <Arduino.h>
#include <Wire.h>
- Wire : communication I²C avec les AS5600
- Arduino.h : fonctions ESP32
🔌 PINOUT
Moteur 1 – ROLL (gauche) (branchement)
RPWM1 = 18 // PWM sens +
LPWM1 = 5 // PWM sens -
REN1 = 2 // Enable droite
LEN1 = 4 // Enable gauche
Moteur 2 – PITCH (droite)
RPWM2 = 19
LPWM2 = 23
REN2 = 32
LEN2 = 33
👉 Les pins PWM sont compatibles LEDC ESP32
👉 REN/LEN servent de sécurité matérielle (enable/disable)
🧭 Capteurs AS5600 (position absolue)
SDA1 / SCL1 → AS5600 moteur 1
SDA2 / SCL2 → AS5600 moteur 2
Deux bus I²C séparés → aucun conflit d’adresse
⚙️ Paramètres importants
#define MIN_POS 200
#define MAX_POS 3900
➡️ Protège mécaniquement (pas de butée)
#define DEADZONE 15
➡️ Évite les oscillations autour de la cible
#define TIMEOUT 300
➡️ Si SimTools s’arrête → moteurs coupés
🎛️ PID (Régulateur) organe de contrôle permettant d’effectuer une régulation en boucle fermée
float Kp = 1.4; // force
float Kd = 0.25; // amortissement
- Pas de Ki → plus stable mécaniquement
- Réglage parfait pour moteurs essuie-glace
📐 Lecture AS5600
uint16_t readAS5600(TwoWire &bus)
- Lecture brute 0–4095
- Position absolue
- Si erreur → retour au centre (2048)
👉 Sécurité logicielle intégrée
⚡ Commande moteur
setMotor(rpwm, lpwm, valeur);
Fonctionnement :
- valeur > 0 → sens 1
- valeur < 0 → sens 2
- petite valeur → moteur arrêté
Zone morte PWM :
if (abs(val) < 5)
🔄 Boucle principale
- Lecture position réelle
- Lecture cible SimTools
- Vérification timeout
- Calcul erreur
- PID (a paramétrer en fonction du simu)
- Envoi PWM moteurs
⏱️ Boucle ≈ 200 Hz (delay 5 ms)
English
Please note, I developed the firmware for the ESP32 microcontroller myself. It works well for me, but I cannot guarantee that there are no bugs or areas for improvement.
Programming is done via the Arduino IDE. Be sure to select the ESP32 board and the correct COM port. Here's an explanation of the program injected into the ESP32 (note that I wrote the code, but I can't guarantee it's bug-free):
📚 Libraries
#include <Arduino.h>
#include <Wire.h>
Wire: I²C communication with the AS5600
Arduino.h: ESP32 functions
🔌 PINOUT
Motor 1 – ROLL (left) (connection)
RPWM1 = 18 // PWM direction +
LPWM1 = 5 // PWM direction -
REN1 = 2 // Enable right
LEN1 = 4 // Enable left
Motor 2 – PITCH (right)
RPWM2 = 19
LPWM2 = 23
REN2 = 32
LEN2 = 33
👉 PWM pins are ESP32 LEDC compatible
👉 REN/LEN serve as hardware safety (enable/disable)
🧭 AS5600 sensors (absolute position)
SDA1 / SCL1 → AS5600 motor 1
SDA2 / SCL2 → AS5600 motor 2
Two separate I²C buses → no address conflicts
⚙️ Important parameters
#define MIN_POS 200
#define MAX_POS 3900
➡️ Mechanically protects (no limit switch)
#define DEADZONE 15
➡️ Prevents oscillations around the target
#define TIMEOUT 300
➡️ If SimTools stops → Motors off
🎛️ PID (Controller) control unit enabling closed-loop regulation
float Kp = 1.4; // force
float Kd = 0.25; // damping
No Ki → more mechanically stable
Perfect setting for wiper motors
📐 AS5600 Read
uint16_t readAS5600(TwoWire &bus)
Raw read 0–4095
Absolute position
If error → return to center (2048)
👉 Built-in software safety
⚡ Motor control
setMotor(rpwm, lpwm, value);
Operation:
Value > 0 → Direction 1
Value < 0 → Direction 2
Small value → Motor stopped
PWM dead zone:
if (abs(val) < 5)
🔄 Main loop
Reads actual position
Reads SimTools target
Checks timeout
Calculates error
PID (to be configured according to the simulator)
Sends motor PWM
⏱️ Loop ≈ 200 Hz (5 ms delay)
🔄 Le Code 🔄 the Code
Pensez a bien sélectionner la bonne carte dans l’IDE ainsi que le bon port com
Le code (à recopier dans l’IDE arduino puis a téléverser dans l’esp32)
English
Remember to select the correct board in the IDE and the correct COM port.
The code (to be copied into the Arduino IDE and then uploaded to the ESP32)
Downloads
4️⃣ MÉCANIQUE (POINT CRUCIAL) 4️⃣ MECHANICS (CRUCIAL POINT)
Le simulateur doit être bien rigide, le centrage de la partie haute du simulateur se fait avec le pilote sur le siège et un tube glissé en dessous pour trouver le point pivot (pour que les moteurs ne force pas trop). Je suis partie avec le haut fait en tube carré de 25mm soudé et une croix pour fixer le cardan.
4️⃣ Quelques étapes :
Découpe des barres de fers à 45°
On teste les longueurs en fonction du pilote et de l’emplacement au sol voulut
On fait gaffe a ses p’tits doigts !
Le support du bas a été fait en bois avec une planche, une poutre ou est relié le cardan et des jambes de force pour supporter l’efforts
⚙️ Cinématique moteurs
MOTEUR 1 MOTEUR 2
(Roll gauche) (Roll droite)
| |
Bras 1 Bras 2
\ /
\ /
[ SIÈGE ]
|
PIVOT
|
BASE
⚙️ Géométrie
- Pivot avant (cardan / rotule)
- Moteurs à l’arrière
- Bras moteurs → biellettes → châssis siège
📏 Longueur des bras moteurs
✅ Recommandé : 45 à 55 mm
🎯 Idéal : 50 mm (axe → rotule)
Poids total Longueur
< 80 kg 55 mm
80–100 kg 45–50 mm
> 100 kg 40–45 mm
📐 Position neutre
- Bras moteur horizontal
- Biellettes verticales (angle a 90° entre le bras et les biellettes)
- AS5600 ≈ 2048
⚠️ Jamais en butée au repos
🔩 Matériel conseillé
- Rotules de quad utilisé ou cardan intérieur de voiture
- Châssis rigide (zéro flexion)
Les moteurs sont montés sur 2 équerres, le bras de levier fait 5cm entre axes pour une courses de 5,5 cm, en général on a un débattement de 7 a10° soit 14 à 20° au total
Le bras de levier (de 5cm) est percé en biseau pour marquer le striage de l’axe du moteur et séré en force
English
The simulator needs to be very rigid. Centering the upper part of the simulator is done with the pilot in the seat and a tube slid underneath to find the pivot point (so the motors don't put too much strain on them). I started with the upper part made from welded 25mm square tubing and a cross brace to attach the gimbal.
4️⃣ A few steps:
Cut the iron bars at 45°
Test the lengths according to the pilot and the desired ground position
Watch your fingers!
The lower support was made of wood with a plank, a beam to which the gimbal is attached, and struts to support the load.
⚙️ Motor kinematics
MOTOR 1 MOTOR 2
(Left roll) (Right roll)
| |
Arm 1 Arm 2
\ /
\ /
[ SEAT ]
|
PIVOT
|
BASE
⚙️ Geometry
Front pivot (cardan joint/ball joint)
Rear-mounted engines
Motor arms → tie rods → seat frame
📏 Motor arm length
✅ Recommended: 45 to 55 mm
🎯 Ideal: 50 mm (axle → ball joint)
Total weight Length
< 80 kg 55 mm
80–100 kg 45–50 mm
> 100 kg 40–45 mm
📐 Neutral position
Motor arm horizontal
Tie rods vertical (90° angle between the arm and the tie rods)
AS5600 ≈ 2048
⚠️ Never fully extended at rest
🔩 Recommended equipment
Ball joints from a used quad or internal car driveshaft
Rigid frame (zero flex)
The engines are mounted on 2 The brackets have a lever arm measuring 5 cm between centers for a 5.5 cm stroke, typically providing a range of motion of 7 to 10°, or 14 to 20° in total.
The 5 cm lever arm is drilled at an angle to match the grooves on the motor shaft and is then press-fitted.
🔩 Ceinture 4 Points 🔩 4-point Belt
Petit rajout de dernière minute car la sécurité c’est important !!! j’ai rajouté une ceinture 4 points qui se serre lorsque l’on frein (on peut même rajouter 2 moteurs qui tendront un coté ou l’autre en fonction de la voiture).
La ceinture 4 points s’accrocher a une partie fixe du bâtis (arrière) tandis que l’autre partie s’accroche au niveau du siege qui lui bouge avec le pilote pour que lorsque l’on frein la ceinture se resserre sur nous
Cela rajoute pas mal au réalisme.
Ceinture 1er prix (que je déconseille pour une vraie voiture…)
La ceinture est accroché au bati du simulateur via un gros ressort (histoire de pas mourir etouffé !) et tendra la ceinture dés que l’on freinera et que le simulateur penchera en avant.
English
A last-minute addition because safety is important! I've added a 4-point seatbelt that tightens when you brake (you can even add two motors that will tighten one side or the other depending on the car).
The 4-point seatbelt attaches to a fixed part of the frame (rear), while the other part attaches to the seat, which moves with the driver so that when you brake, the seatbelt tightens around you.
This adds a lot to the realism. (I don't recommend using a cheap seatbelt for a real car...) The seatbelt is attached to the simulator frame with a large spring (so you don't suffocate!) and will tighten as soon as you brake and the simulator tilts forward.
5️⃣ PARAMÉTRAGE SIMTOOLS V3 5️⃣ SIMTOOLS V3 SETUP
Dans simtools v3, il faut en 1er télécharger le pluging sérial puis le paramétrer :
choisir le bon port com, vitesse 115200, 8bit de données, pas de parité et un bit de stop.
On met une résolution de 10 bits (rapport a l’AS5600 qui utilise une plage de 0 à 4096)
Dans interface Output on extrait les 2 1er axes (2 DOF) du jeu : <Axis1a>, <Axis2a> toutes les 10 ms (les espaces devant <Axis1a> et <Axis2a> sont important)
Il faut aussi télécharger le plugin « Generic 2D Advanced »
Après avoir télécharger les plugins du jeu que l’on souhaite, on fait le paramétrage (en n’oubliant pas d’inverser quelques commandes moteurs et d’avoir mis aussi des paramètres dans « Flt » puis après avoir sauvé le paramétrage on peut tester via le bouton Test setting, si ça bouge c’est bien ! si le mouvement effectué (Pitch Surge Sway etc…) va dans le bon sens c’est encore mieux !
Essayez de ne pas dépasser 120 /130% dans l’Axis Total
- Output type : Serial
- Valeurs envoyées : 200 → 3900
- Sway / Surge / Heave /Roll / Pitch :
- Augmenter progressivement
- Smoothing faible
J’utilise aussi un dernier plugin (Game Plugin Builder ) qui visuellement va faire bouger une représentation de la voiture en fonction des forces (il ne fonctionnera que en cour de jeux) il vaut mieux avoir un 2eme écran pour pouvoir l’afficher et modifier a la voler des réglage dans simtools
English
In simtools v3, you must first download the serial plugin and then configure it:
choose the correct COM port, speed 115200, 8 data bits, no parity, and one stop bit. We set a 10-bit resolution (compared to the AS5600 which uses a range of 0 to 4096).
In the Output interface, we extract the first two axes (2 DOF) of the game: <Axis1a>, <Axis2a> every 10 ms (the spaces before <Axis1a> and <Axis2a> are important).
You also need to download the "Generic 2D Advanced" plugin.
After downloading the plugins for the game you want, you configure the settings (remembering to reverse some motor commands and also to add parameters in "Flt"). After saving the settings, you can test using the Test setting button. If it moves, that's good! If the movement (Pitch, Surge, Sway, etc.) is in the correct direction, that's even better!
Try not to exceed 120/130% in the Total Axis.
Output type: Serial
Values sent: 200 → 3900
Sway / Surge / Heave / Roll / Pitch:
Increase gradually
Smoothing low
I also use one last plugin (Game Plugin Builder) which visually moves a representation of the car according to the forces (it only works during gameplay). It's best to have a second monitor to display it and adjust settings on the fly in SimTools.
6️⃣ CHECK-LIST AVANT UTILISATION 6️⃣ CHECKLIST BEFORE USE
✅ Moteurs arrêtés si SimTools stop
✅ Pas de mouvement au démarrage
✅ Bras jamais en butée
✅ Timeout fonctionnel
✅ Pas d’oscillation au centre
7️⃣ AMÉLIORATIONS POSSIBLES (OPTIONNEL)
🔹 Coup de poing matériel (coupe alim moteurs)
🔹 Filtrage vitesse (accélération progressive)
🔹 EEPROM pour sauvegarder centre
🏆 CONCLUSION
👉 On a maintenant un simulateur fonctionnel, félicitation !
On peut rajouter :
-Rajouter un moteur avec une masselotte désaxé pour simuler les vibrations du moteur, rajouter un casque de réalité virtuel (attention au mal des transport…)
-bass shakers pour la pédale de frein, ainsi que pour simuler les vibreurs, et vibration moteur
-tensionneur de harnais
-Wind simulator pour la sensation de vitesse
-frein à main rally
-clavier magnétique pour virer souris, clavier et à dispo une fois installé
-boutons pour les fonctions du véhicule (démarrer, essuis glaces, traction control, etc...)
-3eme DOF pour sentir la voiture chasser ou carrément 6 DOF…
Les modif sont infinis 😊
Bon bricolage
@Domochris.fr
ps: vous pouvez retrouver ce tuto sur mon site : http://christoams.hd.free.fr/domogeek/site/2026/%F0%9F%8F%81%20TUTORIEL%20COMPLET%20Simulateur%20Simracing%202DOF%20DIY%20web.htm
English
✅ Motors stop if SimTools stops
✅ No movement at startup
✅ Arm never reaches its limit
✅ Functional timeout
✅ No center oscillation
7️⃣ POSSIBLE IMPROVEMENTS (OPTIONAL)
🔹 Physical cutoff (motor power cut)
🔹 Speed filtering (progressive acceleration)
🔹 EEPROM for center saving
🏆 CONCLUSION
👉 We now have a working simulator, congratulations!
You can add:
- Add a motor with an offset weight to simulate engine vibrations, add a virtual reality headset (beware of motion sickness…)
- Bass shakers for the brake pedal, as well as to simulate the rumble strips and engine vibration
- Harness tensioner
- Wind simulator for the sensation of speed
- Rally handbrake
- Magnetic keyboard to replace the mouse and keyboard, and available once installed
- Buttons for vehicle functions (start, wipers, traction control, etc.)
- 3rd DOF to feel the car drift or even 6 DOF…
The modifications are endless 😊
Happy tinkering!
@Domochris.fr
ps: You can find this tutorial on my website: http://christoams.hd.free.fr/domogeek/site/2026/%F0%9F%8F%81%20TUTORIEL%20COMPLET%20Simulateur%20Simracing%202DOF%20DIY%20web.htm