Simracing 2DOF – DIY

by christoams in Workshop > Cars

114 Views, 1 Favorites, 0 Comments

Simracing 2DOF – DIY

image066.png
Simulateur dynamique 2 DOF DIY#simracing

Construction d’un simulateur dynamique avec des moteurs d’essuie-glace de camion

Simulateur 2DOF – ESP32 + BTS7960 + AS5600 + SimTools v3

English

Building a dynamic simulator with truck windshield wiper motors

2DOF simulator – ESP32 + BTS7960 + AS5600 + SimTools v3

Supplies

image067.png

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)

image067.png
image073.jpg
image075.jpg
image077.jpg
image079.jpg
image080.jpg
image084.jpg
image085.jpg

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>

  1. Wire : communication I²C avec les AS5600
  2. 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

  1. Pas de Ki → plus stable mécaniquement
  2. Réglage parfait pour moteurs essuie-glace


📐 Lecture AS5600

uint16_t readAS5600(TwoWire &bus)

  1. Lecture brute 0–4095
  2. Position absolue
  3. Si erreur → retour au centre (2048)

👉 Sécurité logicielle intégrée


⚡ Commande moteur

setMotor(rpwm, lpwm, valeur);

Fonctionnement :

  1. valeur > 0 → sens 1
  2. valeur < 0 → sens 2
  3. petite valeur → moteur arrêté

Zone morte PWM :

if (abs(val) < 5)


🔄 Boucle principale

  1. Lecture position réelle
  2. Lecture cible SimTools
  3. Vérification timeout
  4. Calcul erreur
  5. PID (a paramétrer en fonction du simu)
  6. 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

image086.jpg

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)

image087.jpg
image088.jpg
image089.jpg
image092.jpg
image093.jpg
image095.jpg
image096.jpg
image097.jpg
image098.jpg
image099.jpg
image100.jpg
image101.jpg
image102.jpg
image103.jpg
image104.jpg
image105.jpg
image107.jpg
image108.jpg
image109.jpg
image110.jpg
image111.png
image112.jpg
image113.jpg
image114.jpg
image115.jpg
image116.jpg


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

  1. Pivot avant (cardan / rotule)
  2. Moteurs à l’arrière
  3. 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

  1. Bras moteur horizontal
  2. Biellettes verticales (angle a 90° entre le bras et les biellettes)
  3. AS5600 ≈ 2048

⚠️ Jamais en butée au repos


🔩 Matériel conseillé

  1. Rotules de quad utilisé ou cardan intérieur de voiture


  1. 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

image118.jpg
image119.jpg
image120.jpg

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

image122.jpg
image123.jpg
image124.jpg
image126.jpg

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


  1. Output type : Serial
  2. Valeurs envoyées : 200 → 3900
  3. Sway / Surge / Heave /Roll / Pitch :
  4. Augmenter progressivement
  5. 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