- 0
- 2 046 words

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 2×32 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.
Petite video :
1️⃣ ARCHITECTURE GÉNÉRALE
Principe
- Les informations des forces d’une voiture sont extraites d’un jeux vidéo
- SimTools calcule les forces Roll / Pitch (etc…)
- Envoie deux valeurs position cible via USB (série)
- ESP32(microcontrôleur) :
- lit la position réelle (AS5600)
- compare avec la cible
- commande les moteurs via BTS7960
- Le siège se déplace autour d’un pivot avant
🎯 Type : 2DOF– moteurs à l’arrière
2️⃣ ÉLECTRONIQUE (BRANCHEMENTS)

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 2×32 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 |
🧭 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.

3️⃣ PROGRAMMATION (EXPLICATION DU 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)
🔄 Le 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) :
/*********************************************************************
SIMULATEUR 2DOF – VERSION COCKPIT FINALE cablage definitif
@Domochris.fr
ESP32 WROOM + 2x BTS7960 + 2x AS5600 + SimTools v3
✔ Pas de shutdown SimTools
✔ Pas de coup de poing logiciel
✔ Position absolue limitée
✔ PID simple (P + D)
✔ Timeout sécurité
*********************************************************************/
#include <Arduino.h>
#include <Wire.h>
/*********************************************************************
PINOUT
*********************************************************************/
// ===== MOTEUR 1 – ROLL (gauche) =====
#define RPWM1 18
#define LPWM1 5
#define REN1 2
#define LEN1 4
// ===== MOTEUR 2 – PITCH (droite) =====
#define RPWM2 19
#define LPWM2 23
#define REN2 32
#define LEN2 33
// ===== AS5600 =====
#define SDA1 16
#define SCL1 17
#define SDA2 21
#define SCL2 22
/*********************************************************************
PARAMÈTRES
*********************************************************************/
// Limites mécaniques (à ajuster)
#define MIN_POS 200
#define MAX_POS 3900
// Zone morte position
#define DEADZONE 15
// Timeout communication SimTools (ms)
#define TIMEOUT 300
// PID (valeurs sûres)
float Kp = 1.4;
float Kd = 0.25;
/*********************************************************************
VARIABLES
*********************************************************************/
TwoWire I2C_1 = TwoWire(0);
TwoWire I2C_2 = TwoWire(1);
float pos1, pos2;
float target1 = 2048;
float target2 = 2048;
float err1, err2;
float lastErr1 = 0, lastErr2 = 0;
float pid1, pid2;
unsigned long lastSerial = 0;
/*********************************************************************
LECTURE AS5600
*********************************************************************/
uint16_t readAS5600(TwoWire &bus)
{
bus.beginTransmission(0x36);
bus.write(0x0C);
if (bus.endTransmission(false) != 0) return 2048;
if (bus.requestFrom(0x36, 2) != 2) return 2048;
uint16_t hi = bus.read();
uint16_t lo = bus.read();
return ((hi << 8) | lo) & 0x0FFF;
}
/*********************************************************************
COMMANDE MOTEUR
*********************************************************************/
void setMotor(int rpwm, int lpwm, float val)
{
val = constrain(val, -255, 255);
// Zone morte PWM
if (abs(val) < 5)
{
ledcWrite(rpwm, 0);
ledcWrite(lpwm, 0);
return;
}
if (val > 0)
{
ledcWrite(rpwm, val);
ledcWrite(lpwm, 0);
}
else
{
ledcWrite(rpwm, 0);
ledcWrite(lpwm, -val);
}
}
/*********************************************************************
SETUP
*********************************************************************/
void setup()
{
Serial.begin(115200);
// I2C AS5600
I2C_1.begin(SDA1, SCL1, 400000);
I2C_2.begin(SDA2, SCL2, 400000);
// Enable BTS7960
pinMode(REN1, OUTPUT); pinMode(LEN1, OUTPUT);
pinMode(REN2, OUTPUT); pinMode(LEN2, OUTPUT);
digitalWrite(REN1, LOW); digitalWrite(LEN1, LOW);
digitalWrite(REN2, LOW); digitalWrite(LEN2, LOW);
// PWM ESP32 – 20 kHz / 8 bits
ledcAttach(RPWM1, 20000, 8);
ledcAttach(LPWM1, 20000, 8);
ledcAttach(RPWM2, 20000, 8);
ledcAttach(LPWM2, 20000, 8);
}
/*********************************************************************
LOOP
*********************************************************************/
void loop()
{
// Lecture position
pos1 = readAS5600(I2C_1);
pos2 = readAS5600(I2C_2);
// Lecture SimTools
if (Serial.available())
{
target1 = Serial.parseFloat();
target2 = Serial.parseFloat();
target1 = constrain(target1, MIN_POS, MAX_POS);
target2 = constrain(target2, MIN_POS, MAX_POS);
lastSerial = millis();
}
// Timeout sécurité
if (millis() – lastSerial > TIMEOUT)
{
digitalWrite(REN1, LOW); digitalWrite(LEN1, LOW);
digitalWrite(REN2, LOW); digitalWrite(LEN2, LOW);
setMotor(RPWM1, LPWM1, 0);
setMotor(RPWM2, LPWM2, 0);
return;
}
// Calcul erreur
err1 = target1 – pos1;
err2 = target2 – pos2;
// Zone morte position
if (abs(err1) < DEADZONE && abs(err2) < DEADZONE)
{
digitalWrite(REN1, LOW); digitalWrite(LEN1, LOW);
digitalWrite(REN2, LOW); digitalWrite(LEN2, LOW);
setMotor(RPWM1, LPWM1, 0);
setMotor(RPWM2, LPWM2, 0);
return;
}
// Activer drivers
digitalWrite(REN1, HIGH); digitalWrite(LEN1, HIGH);
digitalWrite(REN2, HIGH); digitalWrite(LEN2, HIGH);
// PID
pid1 = Kp * err1 + Kd * (err1 – lastErr1);
pid2 = Kp * err2 + Kd * (err2 – lastErr2);
lastErr1 = err1;
lastErr2 = err2;
// Commande moteurs
setMotor(RPWM1, LPWM1, pid1);
setMotor(RPWM2, LPWM2, pid2);
delay(5);
}
4️⃣ MÉCANIQUE (POINT CRUCIAL)
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 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



🔩 Ceinture 4 points
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.

5️⃣ PARAMÉTRAGE SIMTOOLS V3
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

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

6️⃣ CHECK-LIST AVANT UTILISATION
✅ 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
