Arduino Leonardo Joystick Library Problemchen

Guten Morgen

Ich habe ein paar Gamecontroler gebastelt, welche auch gut funktionieren. Einziges Problem, das Spiel bekommt nicht alle Aktionen mit, obwohl sie im Gamecontroller Controlpanel von Windows angezeigt werden. Der Gamecontroller besteht aus mehreren Rotary Switchen welche viele Positionen haben. Beim Umschalten überspringt man mehrere Positionen und das sorgt dafür, das der Simulator nicht alles mit macht.

Verwenden tue ich die Joystick Library von MHeironimus

Die Idee ist es die Zeit zu messen wie lange der Schalter in Position X ist und wenn er lange genug dort ist, dann ensprechend den button zu drücken.

Dazu habe ich folgenden Code geschrieben, der prüft ob der Pin 50ms auf Gnd gezogen wurde und wenn ja dann den Button entsprechend High oder Low setzen soll. Nun es tut sich aber garnichts.

Füge ich Serialpriont hinzu, dann bekomme ich die Ausgabe entsprechend aber komischerweise
funktioniert der Joystick nicht.

Habt ihr eine Idee, wie ich nonsense Input unterdrücken kann oder wo mein Fehler liegt?

#include <Joystick.h>

const int pin9 = 9;    
unsigned long previousMillis = 0;  
const long interval = 250;  

Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,JOYSTICK_TYPE_GAMEPAD,
  1, 0,                  // Button Count, Hat Switch Count
  false, false, false,      // No X, Y and Z Axis
  false, false, false,    // No Rx, Ry, or Rz
  false, false,           // No rudder or throttle
  false, false, false);   // accelerator and brake, but No steering

void setup() {
  Serial.begin(9600);
  pinMode(pin9, INPUT_PULLUP);  
}

void loop() {
  // Aktuelle Millisekunde abrufen
  unsigned long currentMillis = millis();

  // Zustand von Pin 9 überprüfen
  if (digitalRead(pin9) == LOW) {
    // Wenn Pin 9 LOW ist, die vorherige Millisekunde aktualisieren
    previousMillis = currentMillis;
  }

  // Überprüfen, ob das Zeitintervall von 50 Millisekunden vergangen ist
  if (currentMillis - previousMillis >= interval) {
    Serial.println("Button 1 nicht gedrückt");
    Joystick.setButton(1, 0);
  } else {
    Serial.println("Button 1 gedrückt");
    Joystick.setButton(0, 1);
    
  }

  delay(10);
}

previousMillis wird solange auf den aktuellen millis() Wert geupdatet solange der Taster an pin 9 gedrückt ist.
Die Kontrolle ob dann 250mS vergangen sind und somit die Ausgaben wechseln erfolgt erst nach loslassen des Tasters.
Grüße Uwe

Hm...

Die Serialprint Anweisung wird aber richtig ausgeführt und da befindet sich auch die Anweisung die Joystick Buttons entsprechend zu triggern.

Deine Bedingung wird sofort beim Schließen des Schalters wahr (gedrückt) PLUS die Dauer deines Intervalls, wenn Du den Schalter wieder öffnest.

Setze dein interval mal auf 2000 hoch, dann siehst Du es.

Und ein Serial.println in

if (digitalRead(pin9) == LOW) {
    // Wenn Pin 9 LOW ist, die vorherige Millisekunde aktualisieren
    previousMillis = currentMillis;
  }

kann nicht schaden...

Schreib mal ins setup()
Joystick.begin();

ins setup()

Ja. Steht da. :wink:

Lol total übersehen das die Zeile fehlt. Hehehe
Danke

So nun weiter denken

Alt:

Neu:

  if (currentMillis - previousMillis >= interval) {
    Serial.println("Button 1 nicht gedrückt");
    Joystick.setButton(0, 0);
  } else {
    Serial.println("Button 1 gedrückt");
    Joystick.setButton(0, 1);

Doppelt gemoppelt. :wink:

1 Like

:roll_eyes:

Ich schäme mich!!!

Ich habe das gerade so und es macht mit dem einem Button schonmal was ich möchte.
Nun muss ich das nur noch auf gefühlt 144.000 Buttons anwenden.

ICH DANKE GANZ GANZ LAUT, DAMIT DAS AUCH JEDER HÖRT!!!

DANKE!!!

#include <Joystick.h>

const int pin9 = 9;    
unsigned long previousMillis = 0;  
const long interval = 2250;  
unsigned long divMillis = 0;

Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,JOYSTICK_TYPE_GAMEPAD,
  1, 0,                  // Button Count, Hat Switch Count
  false, false, false,      // No X, Y and Z Axis
  false, false, false,    // No Rx, Ry, or Rz
  false, false,           // No rudder or throttle
  false, false, false);   // accelerator and brake, but No steering

void setup() {
  Serial.begin(9600);
  pinMode(pin9, INPUT_PULLUP);  
  Joystick.begin();
}

void loop() {
  // Aktuelle Millisekunde abrufen
  unsigned long currentMillis = millis();

  if (digitalRead(9) == 1){
    previousMillis = currentMillis;
    Serial.print("prev Millis = ");
    Serial.print(previousMillis);
    Serial.print(" ");
  }

  if (currentMillis - previousMillis >= interval){
    Serial.println("Button1 High"); 
    Joystick.setButton(0, 1);
  }
  else {
    Serial.println("Button1 Low"); 
    Joystick.setButton(0, 0);
  }
  
  delay(10);
}

Auf wieviele tatsächlich?
Ich würde das ggfls. versuchen mit einen Array zu erschlagen.

Das sind 37 Schalter auf die es angewendet werden muss.

Mit Arrays bin ich absolut nicht vertraut bzw muss ich bei jedem Joystick 1 Button auf Low lassen, das macht 2 Button pro Panel.

Das blöde Discord zwingt mich leider dazu. Weißt man zum Beispiel Button 2 als PTT zu, ist jeder Button 2 von egal welchem Controller auch PTT.

Das wäre blöd bei einem Drehschalter. Und jeder hat mindestens 5 Controller im Simulator. Tendenz steigend.

Die Arrays bekomme ich so schnell nicht in meinen Kopf. Ich bin Techniker und kein Programmierer. Wir haben komplett andere Denkweisen in unseren Köpfen. Da habt ihr mir gegenüber einen Vorteil. Ich werfe nur Codeschnippsel zusammen und hoffe das ich sie entsprechend anpassen kann so das es läuft.

Arrays?
Vieleicht nicht für 144.000 aber für 50.
Grüße Uwe

#include <Joystick.h>

const byte inputPin[] = {9, 10};
const byte pinNumbers = sizeof(inputPin) / sizeof(inputPin[0]);

unsigned long previousMillis[pinNumbers] = {0};
const unsigned long interval = 2250;
unsigned long divMillis = 0;

Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_GAMEPAD,
                   pinNumbers, 0,                  // Button Count, Hat Switch Count
                   false, false, false,      // No X, Y and Z Axis
                   false, false, false,    // No Rx, Ry, or Rz
                   false, false,           // No rudder or throttle
                   false, false, false);   // accelerator and brake, but No steering

void setup()
{
  Serial.begin(9600);
  for (byte b = 0; b < pinNumbers; b++)
  { pinMode(inputPin[b], INPUT_PULLUP); }
  Joystick.begin();
}

void loop()
{
  unsigned long currentMillis = millis();
  for (byte b = 0; b < pinNumbers; b++)
  {
    if (digitalRead(inputPin[b]) == 1)
    { previousMillis[b] = currentMillis; }
    Joystick.setButton(b, currentMillis - previousMillis[b] >= interval);
  }
  delay(10);
}

Dein Pin 9 muss noch immer genauso funktionieren wie bisher.

Aehm... Am leonardo?

Genau genommen sind ein paar wenige mehr als 37 aber das "warten" das der Pin auf gnd bleibt ist bei den anderen Pins nicht nötig.

Nur bei den Drehschaltern.

Ich verwende 2 MCP23017 zur Porterweiterung.

Dann spiel mal den da oben ein -der muss jetzt auf PIN 9 und 10 reagieren.
Der Rest sollte ja nu nicht ganz so schlimm sein.
Musst nur vernünftig beschreiben, was wann und wie passieren soll...

Der Code steht schon für die Panels, der Rest ist nur eine Fleißarbeit um den Code nun entsprechend anzupassen.

Dann mach nen Haken ran.
Ich dachte Du wolltest noch was lernen.

Was ist eigentlich wenn currentMillis 4294967295 übersteigt?