Connecter servo moteur simhub

Salut je cherche comment connecter des servo moteur 270© et led pour les clignotants et voyant température et essence connecter sur une Arduino Uno j'ai déjà mis le protocole simhub et mis un code teste pour tester les moteurs et la je bloque pour activer les aiguille en fonction du jeu si vous pouvez m'aider :sweat_smile: je vais vous mettre tout les branchements et code en dessous .

Protocole simhub

format([DataCorePlugin.GameData.NewData.SpeedKmh],'0') + ';' +
isnull([DataCorePlugin.GameData.NewData.Rpms],'0') + ';' +
isnull([DataCorePlugin.Computed.Fuel_Percent],'0') + ';' +
isnull([DataCorePlugin.GameData.NewData.WaterTemperature],'0') + ';' +
isnull([TurnIndicatorLeft],'0') + ';' +
isnull([TurnIndicatorRight],'0') + ';'


Branchement Arduino/

LEDs :

Pin 2 → Cligno gauche

Pin 3 → Cligno droit

Pin 4 → Voyant essence (réserve)

Pin 5 → Voyant température

Servos :

Pin 8 → Vitesse (Km/h)

Pin 9 → RPM

Pin 10 → Essence

Pin 11 → Température

Code teste Arduino

#include <Servo.h>

// --- LEDs (voyants) ---
const int ledClignoGauche = 2;
const int ledClignoDroite = 3;
const int ledEssence      = 4; // Réserve
const int ledTemp         = 5; // Surchauffe

// --- Servos ---
Servo servoVitesse;
Servo servoRPM;
Servo servoEssence;
Servo servoTemp;

// --- Plages servos ---
int speedMinServo = 10;
int speedMaxServo = 210;

int rpmMinServo = 0;
int rpmMaxServo = 7500;

int fuelMinServo = 0;
int fuelMaxServo = 55;

int tempMinServo = 0;
int tempMaxServo = 55;

// --- Variables pour lissage ---
float displaySpeed = speedMinServo;
float displayRPM = rpmMinServo;
float displayFuel = fuelMinServo;
float displayTemp = tempMinServo;

// --- Vitesse de lissage (plus grand = plus lent) ---
float smoothFactor = 20.0;

// --- Clignotants ---
bool clignoState = false;
unsigned long lastClignoToggle = 0;
const unsigned long clignoInterval = 500;

// --- Direction de test (monte/descend) ---
int direction = 1;

void setup() {
  servoVitesse.attach(8);
  servoRPM.attach(9);
  servoEssence.attach(10);
  servoTemp.attach(11);

  pinMode(ledClignoGauche, OUTPUT);
  pinMode(ledClignoDroite, OUTPUT);
  pinMode(ledEssence, OUTPUT);
  pinMode(ledTemp, OUTPUT);
}

void loop() {
  // --- RPM et km/h synchronisés ---
  float targetSpeed = direction > 0 ? speedMaxServo : speedMinServo;
  float targetRPM   = direction > 0 ? rpmMaxServo : rpmMinServo;

  displaySpeed += (targetSpeed - displaySpeed) / smoothFactor;
  displayRPM   += (targetRPM - displayRPM) / smoothFactor;

  if(abs(displaySpeed - targetSpeed) < 1.0) direction *= -1;

  servoVitesse.write(displaySpeed);
  servoRPM.write(displayRPM);

  // --- Essence et température ---
  float targetFuel = direction > 0 ? fuelMaxServo : fuelMinServo;
  float targetTemp = direction > 0 ? tempMaxServo : tempMinServo;

  displayFuel += (targetFuel - displayFuel) / smoothFactor;
  displayTemp += (targetTemp - displayTemp) / smoothFactor;

  servoEssence.write(displayFuel);
  servoTemp.write(displayTemp);

  // --- Voyants ---
  digitalWrite(ledEssence, displayFuel <= fuelMinServo ? HIGH : LOW);
  digitalWrite(ledTemp, displayTemp >= tempMaxServo ? HIGH : LOW);

  // --- Clignotants ---
  unsigned long currentMillis = millis();
  if(currentMillis - lastClignoToggle >= clignoInterval){
    clignoState = !clignoState;
    digitalWrite(ledClignoGauche, clignoState ? HIGH : LOW);
    digitalWrite(ledClignoDroite, clignoState ? HIGH : LOW);
    lastClignoToggle = currentMillis;
  }

  delay(30); // fluidité
}

Pour utiliser des LEDs

Pour utiliser un servomoteur

Bonjour oui j'ai bien compris le fonctionnement des led et du servo moteur mais le souci c'est que je n'arrive pas a synchroniser correctement l'aiguille accélérateur et rpm genre quand je suis à 80 km dans le jeu mon aiguille commence à peine à monter et les RPM à 2000 tours sur le jeu les RPM sur mon compteur sur un fond

Bonjour coco1224fr

Dans ton cas, il est important de voir "vivre" le programme en y mettant des Serial.print de variables.

Mettre:

Void setup() {
  Serial.begin(115200);

Je t'y ai mis un exemple:
Serial.print("Servo RPM = " + String(displaySpeed));

Ton programme:

#include <Servo.h>

// --- LEDs (voyants) ---
const int ledClignoGauche = 2;
const int ledClignoDroite = 3;
const int ledEssence      = 4; // Réserve
const int ledTemp         = 5; // Surchauffe

// --- Servos ---
Servo servoVitesse;
Servo servoRPM;
Servo servoEssence;
Servo servoTemp;

// --- Plages servos ---
int speedMinServo = 10;
int speedMaxServo = 210;

int rpmMinServo = 0;
int rpmMaxServo = 7500;

int fuelMinServo = 0;
int fuelMaxServo = 55;

int tempMinServo = 0;
int tempMaxServo = 55;

// --- Variables pour lissage ---
float displaySpeed = speedMinServo;
float displayRPM = rpmMinServo;
float displayFuel = fuelMinServo;
float displayTemp = tempMinServo;

// --- Vitesse de lissage (plus grand = plus lent) ---
float smoothFactor = 20.0;

// --- Clignotants ---
bool clignoState = false;
unsigned long lastClignoToggle = 0;
const unsigned long clignoInterval = 500;

// --- Direction de test (monte/descend) ---
int direction = 1;

Void setup() {
  Serial.begin(115200);
  servoVitesse.attach(8);
  servoRPM.attach(9);
  servoEssence.attach(10);
  servoTemp.attach(11);

  pinMode(ledClignoGauche, OUTPUT);
  pinMode(ledClignoDroite, OUTPUT);
  pinMode(ledEssence, OUTPUT);
  pinMode(ledTemp, OUTPUT);
}

void loop() {
  // --- RPM et km/h synchronisés ---
  float targetSpeed = direction > 0 ? speedMaxServo : speedMinServo;
  float targetRPM   = direction > 0 ? rpmMaxServo : rpmMinServo;

  displaySpeed += (targetSpeed - displaySpeed) / smoothFactor;
  displayRPM   += (targetRPM - displayRPM) / smoothFactor;

  if(abs(displaySpeed - targetSpeed) < 1.0) direction *= -1;

  Serial.print("Servo RPM = " + String(displaySpeed));
  servoVitesse.write(displaySpeed);
  servoRPM.write(displayRPM);

  // --- Essence et température ---
  float targetFuel = direction > 0 ? fuelMaxServo : fuelMinServo;
  float targetTemp = direction > 0 ? tempMaxServo : tempMinServo;

  displayFuel += (targetFuel - displayFuel) / smoothFactor;
  displayTemp += (targetTemp - displayTemp) / smoothFactor;

  servoEssence.write(displayFuel);
  servoTemp.write(displayTemp);

  // --- Voyants ---
  digitalWrite(ledEssence, displayFuel <= fuelMinServo ? HIGH : LOW);
  digitalWrite(ledTemp, displayTemp >= tempMaxServo ? HIGH : LOW);

  // --- Clignotants ---
  unsigned long currentMillis = millis();
  if(currentMillis - lastClignoToggle >= clignoInterval){
    clignoState = !clignoState;
    digitalWrite(ledClignoGauche, clignoState ? HIGH : LOW);
    digitalWrite(ledClignoDroite, clignoState ? HIGH : LOW);
    lastClignoToggle = currentMillis;
  }

  delay(30); // fluidité
}

A toi de mettre d'autres print.

Cordialement
jpbbricole

Bonjour merci pour votre aide j'ai réussi a bien connecter les servo moteur et led a simhub la je cherche juste comment bien synchroniser les kmh et température je vous mets ce que j'ai mis sur SIM hub ci-dessous ainsi que le code Arduino que j'utilise et la vidéo qui montre le compteur en fonctionnement

Protocole simhub

format([DataCorePlugin.GameData.NewData.SpeedKmh],'0') + ';' +
isnull([DataCorePlugin.GameData.NewData.Rpms],'0') + ';' +
isnull([DataCorePlugin.GameData.NewData.WaterTemperature],'0') + ';' +
isnull([DataCorePlugin.Computed.Fuel_Percent],'0') + ';' +
isnull([DataCorePlugin.GameRawData.Damage.WearEngine],'0') + ';' +
isnull([TurnIndicatorLeft],'0') + ';' +
isnull([TurnIndicatorRight],'0') + ';' +
isnull([DataCorePlugin.GameRawData.Lights.HighBeams],'0') + '\n'


Code Arduino

#include <Servo.h>

// --- Servos ---
Servo servoVitesse;
Servo servoRPM;
Servo servoEssence;
Servo servoTemp;

// --- Voyants ---
const int ledEssence = 4;
const int ledTemp    = 5;
const int ledClignoG = 2;
const int ledClignoD = 3;

// --- Broches servos ---
const int pinVitesse = 8;
const int pinRPM     = 9;
const int pinEssence = 10;
const int pinTemp    = 11;

// --- Angles ---
int speedMin = 180, speedMax = 0;    // Km/h inversé
int rpmMin   = 180, rpmMax   = 0;    // RPM inversé
int fuelMin  = 0, fuelMax  = 55;     // Essence
int tempMin  = 55, tempMax  = 0;     // Température inversé

// --- Variables SimHub ---
int speed = 0;
int rpm   = 0;
int fuel  = 0;
int temp  = 0;
int turnLeft = 0;
int turnRight = 0;

// --- Variables pour lissage ---
float displaySpeed = speedMin;  
float displayRPM   = rpmMin;    
float displayFuel  = fuelMin;   
float displayTemp  = tempMin;   

// --- Lissage ---
const float smoothSpeed = 5.0;
const float smoothRPM   = 5.0;
const float smoothFuel  = 10.0;
const float smoothTemp  = 8.0;

void setup() {
  Serial.begin(115200);

  servoVitesse.attach(pinVitesse);
  servoRPM.attach(pinRPM);
  servoEssence.attach(pinEssence);
  servoTemp.attach(pinTemp);

  pinMode(ledEssence, OUTPUT);
  pinMode(ledTemp, OUTPUT);
  pinMode(ledClignoG, OUTPUT);
  pinMode(ledClignoD, OUTPUT);

  // Positions initiales
  servoVitesse.write(displaySpeed);
  servoRPM.write(displayRPM);
  servoEssence.write(displayFuel);
  servoTemp.write(displayTemp);

  digitalWrite(ledEssence, HIGH); // Essence bas
  digitalWrite(ledTemp, LOW);     // Température haut, LED éteinte
}

void loop() {
  // --- Lecture Serial SimHub ---
  if (Serial.available()) {
    String line = Serial.readStringUntil('\n');
    int values[7];
    int i = 0;
    int fromIndex = 0;
    int semicolonIndex = line.indexOf(';');
    while (semicolonIndex >= 0 && i < 7) {
      values[i++] = line.substring(fromIndex, semicolonIndex).toInt();
      fromIndex = semicolonIndex + 1;
      semicolonIndex = line.indexOf(';', fromIndex);
    }
    if (i < 7) values[i] = line.substring(fromIndex).toInt();

    speed     = values[0];
    rpm       = values[1];
    temp      = values[2];
    fuel      = values[3];
    turnLeft  = values[5];
    turnRight = values[6];
  }

  // --- Lissage et mise à jour servos ---
  displaySpeed += (speed - displaySpeed) / smoothSpeed;
  displayRPM   += (rpm - displayRPM) / smoothRPM;
  displayFuel  += (fuel - displayFuel) / smoothFuel;
  displayTemp  += (temp - displayTemp) / smoothTemp;

  servoVitesse.write(map(displaySpeed, 0, 210, speedMin, speedMax));
  servoRPM.write(map(displayRPM, 0, 7500, rpmMin, rpmMax));
  servoEssence.write(map(displayFuel, 0, 100, fuelMin, fuelMax));
  servoTemp.write(map(displayTemp, 0, 120, tempMin, tempMax));

  // --- Voyants LED ---
  digitalWrite(ledEssence, (displayFuel <= 5) ? HIGH : LOW);
  digitalWrite(ledTemp, (displayTemp >= 50) ? HIGH : LOW); // Température vers le bas LED ON
  digitalWrite(ledClignoG, turnLeft ? HIGH : LOW);
  digitalWrite(ledClignoD, turnRight ? HIGH : LOW);

  delay(20);
}

Vidéo
Vidéo du fonctionnement compteur

Si je comprends bien, ce n'est pas un problème de synchronisation, les aiguilles bougent en même temps, mais plutôt un problème d'échelle, l'aiguille de ton tableau de bord n'est pas au bon endroit.


En l'état, tu mappes une vitesse comprise entre 0 et 210 kh/h dans un angle qui va de 180° à 0°. Et cela ne correspond pas à l'angle que devrait faire l'aiguille dans ton compteur de vitesse.
L'impulsion envoyée pour 180° ne correspond pas toujours à la position maximum du servo.
Tu ferais peut-être mieux de passer en argument la durée de l'impulsion plutôt qu'un angle. C'est plus précis et cela offre plus de souplesse.
Cela demande un peut de tâtonnement pour trouver les valeurs de l'impulsion min et de l'impulsion max mais le résultat est meilleur. En théorie l'impulsion min c'est 1000μs et l'impulsion max c'est 2000μs. Mais le servo peut accepter des valeurs inférieures à 1000 et des valeurs supérieures à 2000, d'où les tâtonnements pour trouver les limites.
Attention à ne pas pousser le servo au-delà de ses limites car cela fait consommer plus de courant et fait souvent vibrer le servo.


A noter, la course de l'aiguille doit dépasser les 180°. Es-tu certain que ton servo est bien capable de couvrir l'angle nécessaire?

Oui c'est un servo moteur 270 degré là c'est bon tout marche juste à partir de 110 et j'ai un petit décalage de 5 km heure j'ai juste ça à régler