Ext. Steuerung für Euro Truck Simulator 2

Hallo,

Ich baue mir gerade eine ControlPanel mit diversen Schaltern um das Computerspiel Euro Truck Simulator 2 etwas komfortabler zu Steuern.
Ich habe einen Arduino Micro Pro hier. habe jetzt das script so gebaut das ich mit Tastern Keyboard Befehle schicken kann das ist jetzt kein Thema.
Das Problem ist der Automatik Schalthebel. Es gibt 3 Stellungen mit dem Getriebe. Vorwärts - Leerlauf - Rückwärts.
Ich habe einen Kippschalter mit 3 Stellungen hier. 2 Eingänge (7 & 9) des Arduinos werden mit den internen Pullup Widerstände eingeschaltet. Habe aber Probleme den Code zu schreiben weil meine fähigkeiten jetzt nicht so hoch sind.
Wenn Eingang 7&9 High sind (Schalter in Mittelstellung, kein Kontakt betätigt) soll Leerlauf eingeschaltet sein ist auch die Standart Spiel Einstellung am Anfang. Einmal die Taste "SHIFT L" schaltet in den Vorwärtsgang ds wollte ich machen indem der Eingang 9 auf LOW geschaltet wird. Um dann wieder in Leerlauf zu kommen muss einmal "STRG" gedrückt werden. Bei einem zweiten Druck auf "STRG" schaltet das Spiel in den Rückwärtsgang. Dann wollte ich Eingang 7 auf LOW schalten. Mit einem Druck auf "SHIFT L" geht das Spiel wieder in den Leerlauf.

Habe es versucht mit den befehlen Keyboard.press und Keyboard.release aber komme da nicht richtig weiter weil die Befehle ja nur bei Statuswechsel des Schalter ausgeführt werden sollen.

Das war mein Ansatz:

// Schalter Gangschaltung
  
  {
  if (digitalRead(7) == LOW)

    {Keyboard.press(129);
    delay(80);
    Keyboard.release(129);}
  else
    {Keyboard.press(128);
    delay(80);
    Keyboard.release(128);}}

 {
  if (digitalRead(9) == LOW)

    {Keyboard.press(128);
    delay(80);
    Keyboard.release(128);}
   else
    {Keyboard.press(129);
    Keyboard.release(129);}}
    


}

Aber er führt das ja bei jedem Loop aus. Das Script müsste eine Variable abfragen ob sie sich geändert hat und dementsprechend reagieren ob er von Vorwärts auf Neutral oder von Rückwärts in Neutral schalten muss.

Für Hilfe wäre ich Dankbar.

PS.

Habe auf dem Arduino die Keyboard Libary installiert um damit Tastatur Befehle auszugeben.

weil die Befehle ja nur bei Statuswechsel des Schalter ausgeführt werden sollen.

Dann musst du das auch machen.
Um auf Änderungen zu reagieren, musst du dir normalerweise die Schalterstellung des letzten loop-Durchlauf merken.

Allerdings versteh ich dich so, dass die Schalter Dauersignale sind, und du dir eher merken musst, in welchem Zustand (vor, leer, rück) dein Truck gerade ist, um gegebenenfalls einen Tastenbefehl zu senden oder eben normalerweise nicht.

Was passiert übrigens, wenn zwischen Schalterstellung "vor" und "zurück" kein leer-Zustand erkannt wird ?

(deleted)

Hier ist mal der Schalplan. Habe ein Arduino Clone Micro Pro. Ist etwas kleiner als im Bild und andere Pins angeklemmt aber so habe ich das angeklemmt und es ist ein Schalter mit 3 Stellungen. Konnte auch im Programm jetzt eine Extra Taste für Leerlauf einstellen.

Das heißt bei "Low" Pin7 schaltet er in Vorwärts, bei "Low" Pin9 schaltet er in Rückwärts und bei "High" Pin7 & Pin9 schaltet er in Leerlauf. Das habe ich alles getestet und im Script drin. Nur bei jedem Loop sendet er halt je nach Schalterstellung dauerhaft seine zugeordnete Taste.

Ich brauch jetzt einen Code wo bei jeden Loop die Schalterstellung abgefragt wird ob sie sich geändert hat und dann nur einmal oder für ein paar ms die entsprechende Taste sendet.

void loop() {
  // Euro Truck Simulator 2 Control Script

  // -------------Schalter für Zubehör-------------
if (digitalRead(0) == LOW) {
    //Send an ASCII 'p',
    Keyboard.press(112);
    delay(150);
    Keyboard.release(112);
  }
  if (digitalRead(1) == LOW) {
    //Send an ASCII 'f',
    Keyboard.press(102);
    delay(150);
    Keyboard.release(102);
    
  }
  // ---------Schalter Gangschaltung---------------
  
  {
  if (digitalRead(7) == LOW)

    {Keyboard.press(129);
    delay(80);
    Keyboard.release(129);}
  
 {
  if (digitalRead(9) == LOW)

    {Keyboard.press(128);
    delay(80);
    Keyboard.release(128);}
    
    {if (digitalRead(9) == HIGH && digitalRead(7) == HIGH)
    Keyboard.press(113);
    delay(80);
    Keyboard.release(113);
    }}}}
    //------------------------------------------

Das ist der Code der zwar noch etwas unsauber aussieht aber im Prinzip funktioniert bis auf das die "Gangschaltung" dauerhaft seine "Signale" schickt.

im Prinzip funktioniert bis auf das die "Gangschaltung" dauerhaft seine "Signale" schickt.

Falsch!
Die anderen Taster senden auch dauerhaft Signale, wenn du sie länger drückst. Das mag zwar gewollt sein oder nicht stören, aber ist dasselbe Verhalten.

Merk dir, ob der Truck bereits fährt (vor/rück).
Dann vergleiche Schalterzustand mit Truckzustand und schalte, wenn es nicht übereinstimmt,
und merke dir den neuen Truckzustand.

{{( Und entferne überflüssige Klammern. So sieht sich das kein vernünftiger Mensch an. )}}

(deleted)

(deleted)

Peter-CAD-HST:
Moin errorflash,
dein Sketch macht genau das was du ihm sagst :slight_smile:
Der Sketch muss den alten Schalterstatus mit einem neuen Schalterstatus vergleichen und wenn eine Änderung festgestellt wird auf die Änderung reagieren und nur dann.
Welchen Namen haben die Schalter 0,1,7 und 9?
Gruß Peter
und gesund bleiben

genau das meine ich nur habe ich keine Ahnung wie das Geht. 0 ist Warnblinker, 1 ist Scheibenwischer, 7 Vorwärts, 9 Rückwärts.

errorflash:
genau das meine ich nur habe ich keine Ahnung wie das Geht.

Ein erweiterungsfähiger Vorschlag, mangels Micro Pro mit einem Nano getestet:

const byte TASTERPIN = 9;
const uint32_t TASTENVERZOEGERUNG = 80; // für prellende Tasten könnte dieser Wert zu klein sein
uint32_t jetzt = millis();

void setup() {
  Serial.begin(115200);
  Serial.println(F("Los geht's"));
  pinMode(TASTERPIN, INPUT_PULLUP); // aktiv LOW
}

void loop() {
  jetzt = millis();
  taster();
}

void taster() {
  static uint32_t vorhin = jetzt;
  static bool einmal = false;
  bool neu = !digitalRead(TASTERPIN);
  static bool alt = neu;
  if (neu && !alt && !einmal) {
    vorhin = jetzt;
    einmal = true;
    Serial.println(F("Taste gedrückt"));
  }
  if (einmal && (jetzt - vorhin >= TASTENVERZOEGERUNG)) {
    einmal = false;
    Serial.println(F("Taste losgelassen"));
  }
  alt = neu;
}

(deleted)

Besten Dank an alle.
Konnte mir jetzt einen Code zusammensetzen mit den Vorlagen von Euch.
Funktioniert jetzt genauso wie ich es wollte. Muss den Code noch etwas bereinigen und keyboard befehle einfügen und dann sollte alles gehen.

Dann solltest Du den Code auch dem Forum zur Verfügung stellen.

Gruß Tommy