Arduino Leonardo Joystick Library

Guten Abend alle miteinander.

Ich hoffe ihr könnt mir schnell und einfach helfen.

Ich bastel gerade ein paar Gamecontroller für mehrere Leute, welche für einen Flugsimulator eingesetzt werden. Der Code funktioniert auch und die Arduinos werden bei mir als 2 Gamecontroller angezeigt und alle Achsen und Buttons und auch das dimmen der LED´s funktioniert via zweiter Funktion inklusive speichern im EEPROM.

Beide Panels die ich bereits an meine Kollegen versendet habe, funktionieren hier bei mir.
Das erste Panel funktioniert ebenfalls beim Empfänger.

Das zweite Panel wird bei seinem Empfänger allerdings nicht als Gamecontroller angezeigt. Er sieht nur einen Arduino. Seltsam hier hat alles funktioniert. Wir haben ebenfalls den Code neu geflasht und das ging auch aber wir haben keinen Gamecontroller.

Also schnell mal einen Arduino geschnappt, den Code drauf geflasht und zack, habe ich die Gamecontroller. Also den Arduino bei meiner Frau (nein in den PC) rein gesteckt und auch da sehe ich nur einen Arduino.

Was ist da los?
Treiber?

Tut mir leid für den Code, ich bin kein Programmierer.

#include <DFRobot_MCP23017.h>
#include <Joystick.h>
#include <EEPROM.h>
#include <MapFloat.h>

#define JOYSTICK_COUNT 2

Joystick_ Joystick[JOYSTICK_COUNT] = {
  Joystick_(0x08, JOYSTICK_TYPE_MULTI_AXIS,  21, 0,  true, true, false, false, false, false, false, false, false, false, false),
  Joystick_(0x04, JOYSTICK_TYPE_JOYSTICK,  24, 0,  true, true,  true,  true, true, false, false, false, false, false, false)
};
bool button;

int leftRot;
int rightRot;
int btn03;
int btn01;

int ledValue = 255;
int newLedValue;
int led = 13; 
float PWMVal = 0;

unsigned long buttonPressStartTime = 0;
unsigned long dimmerStartTime = 0;
unsigned long button24StartTime = 0;
const int requiredLongPressTime = 5000;  // 5 Sekunden für den langen Druck
const int requiredShortPressTime = 500; // 1 Sekunde für den kurzen Druck
const int button24Duration = 300;        // 300 Millisekunden für button24

boolean buttonPressed = false;
boolean button24Activated = false;
boolean dimmerActivated = false;




DFRobot_MCP23017 mcp2(Wire, 0x20);
DFRobot_MCP23017 mcp1(Wire, 0x27);//constructor, change the Level of A2, A1, A0 via DIP switch to revise the I2C address within 0x20~0x27.
//DFRobot_MCP23017 mcp;//use default parameter, Wire  0x27(default I2C address)

//Prepare: connect a button to a digital pin of the IO expansion board(eg: eGPA0)
void setup() {

  ledValue = EEPROM.read(0);


  Serial.begin(9600);
  /*wait for the chip to be initialized completely, and then exit*/
  while(mcp1.begin() != 0){
   Serial.println("Initialization of the chip1 failed, please confirm that the chip connection is correct!");
    delay(1000);
  }

  while(mcp2.begin() != 0){
   Serial.println("Initialization of the chip2 failed, please confirm that the chip connection is correct!");
    delay(1000);
  }
  /*pinMode function is used to set the pin mode of module Parameter pin, the available parameter is shown below:
  eGPA0  eGPA1  eGPA2  eGPA3  eGPA4  eGPA5  eGPA6  eGPA7  eGPA  eGPB0  eGPB1  eGPB2  eGPB3  eGPB4  eGPB5  eGPB6  eGPB7  eGPB
   0       1      2      3      4      5      6      7      8       9      10     11     12     13     14     15
  Parameter mode, can be set to: INPUT, OUTPUT, INPUT_PULLUP(internal 100KΩ pull-up resistor)
  */
  mcp1.pinMode(/*pin = */mcp1.eGPA, /*mode = */INPUT_PULLUP);
  mcp1.pinMode(/*pin = */mcp1.eGPB, /*mode = */INPUT_PULLUP);
  mcp2.pinMode(/*pin = */mcp2.eGPA, /*mode = */INPUT_PULLUP);
  mcp2.pinMode(/*pin = */mcp2.eGPB, /*mode = */INPUT_PULLUP);
  /*Set all Group GPIOA and B pins to input*/

  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);
  pinMode(7, INPUT_PULLUP);
  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);
  pinMode(led, OUTPUT);

  Joystick[0].begin();
  Joystick[1].begin();
  
}

void loop() {


  analogWrite(led, ledValue);
  while (Serial.available()>0){
  String myString = Serial.readString(); // Read as String
  float myFloat = myString.toFloat();   // Convert it to float
  float PWMVal = mapFloat (myFloat, 0,10.0,0,255); // 0->0 , 10->255

  if (ledValue != PWMVal){
    ledValue = PWMVal;
    EEPROM.write(0, ledValue);
  }

  analogWrite(led, ledValue);        // Output
  Serial.print("LEVEL = ");
  Serial.println(myFloat);           
  Serial.print ("PMW VALUE = ");
  Serial.println (PWMVal);

  Serial.print ("ledValue = ");
  Serial.println (ledValue);
  Serial.println("----------------------------");
  }


  /*digitalRead function is used to read the Level of a digital pin. The pin needs to be set to input mode before using this function. 
  Parameter pin, the available parameter is shown below:
  eGPA0  eGPA1  eGPA2  eGPA3  eGPA4  eGPA5  eGPA6  eGPA7  eGPA
   0       1      2      3      4      5      6      7
  eGPB0  eGPB1  eGPB2  eGPB3  eGPB4  eGPB5  eGPB6  eGPB7  eGPB
   8       9      10     11     12     13     14     15
  */
//temp00 = mcp.digitalRead(mcp.eGPA0);
//temp01 = mcp.digitalRead(mcp.eGPA1);

//Buttons for Joystick #0

  if (mcp1.digitalRead(mcp1.eGPB0) == 0){
    Joystick[0].setButton(0, 1);
  } else {
    Joystick[0].setButton(0, 0);
  }

  if (mcp1.digitalRead(mcp1.eGPB0) == 1 && mcp1.digitalRead(mcp1.eGPB1) == 1){
    Joystick[0].setButton(1, 1);
  } else {
    Joystick[0].setButton(1, 0);
  }

  if (mcp1.digitalRead(mcp1.eGPB1) == 0){
    Joystick[0].setButton(2, 1);
  } else {
    Joystick[0].setButton(2, 0);
  }
  
  Joystick[0].setButton(4, 0);  //Button 5 for Discord

    if (mcp1.digitalRead(mcp1.eGPA7) == 0){
    Joystick[0].setButton(3, 1);
    Joystick[0].setButton(5, 0);
  } else {
    Joystick[0].setButton(3, 0);
    Joystick[0].setButton(5, 1);
  }

  if (mcp1.digitalRead(mcp1.eGPA6) == 0){
    Joystick[0].setButton(6, 1);
    Joystick[0].setXAxis(0);
  } else {
    Joystick[0].setButton(6, 0);
  }

  if (mcp1.digitalRead(mcp1.eGPA5) == 0){
    Joystick[0].setButton(7, 1);
    Joystick[0].setXAxis(170);
  } else {
    Joystick[0].setButton(7, 0);
  }

  if (mcp1.digitalRead(mcp1.eGPA4) == 0){
    Joystick[0].setButton(8, 1);
    Joystick[0].setXAxis(340);
  } else {
    Joystick[0].setButton(8, 0);
  }

  if (mcp1.digitalRead(mcp1.eGPA3) == 0){
    Joystick[0].setButton(9, 1);
    Joystick[0].setXAxis(511);
  } else {
    Joystick[0].setButton(9, 0);
  }

  if (mcp1.digitalRead(mcp1.eGPA2) == 0){
    Joystick[0].setButton(10, 1);
    Joystick[0].setXAxis(682);
  } else {
    Joystick[0].setButton(10, 0);
  }

  if (mcp1.digitalRead(mcp1.eGPA1) == 0){
    Joystick[0].setButton(11, 1);
    Joystick[0].setXAxis(853);
  } else {
    Joystick[0].setButton(11, 0);
  }

  if (mcp1.digitalRead(mcp1.eGPA0) == 0){
    Joystick[0].setButton(12, 1);
    Joystick[0].setXAxis(1024);
  } else {
    Joystick[0].setButton(12, 0);
  }

  if (mcp2.digitalRead(mcp2.eGPB7) == 0){
    Joystick[0].setButton(13, 1);
    Joystick[0].setYAxis(0);
  } else {
    Joystick[0].setButton(13, 0);
  }

  if (mcp2.digitalRead(mcp2.eGPB6) == 0){
    Joystick[0].setButton(14, 1);
    Joystick[0].setYAxis(146);
  } else {
    Joystick[0].setButton(14, 0);
  }

  if (mcp2.digitalRead(mcp2.eGPB5) == 0){
    Joystick[0].setButton(15, 1);
    Joystick[0].setYAxis(292);
  } else {
    Joystick[0].setButton(15, 0);
  }

  if (mcp2.digitalRead(mcp2.eGPB4) == 0){
    Joystick[0].setButton(16, 1);
    Joystick[0].setYAxis(438);
  } else {
    Joystick[0].setButton(16, 0);
  }

  if (mcp2.digitalRead(mcp2.eGPB3) == 0){
    Joystick[0].setButton(17, 1);
    Joystick[0].setYAxis(585);
  } else {
    Joystick[0].setButton(17, 0);
  }

  if (mcp2.digitalRead(mcp2.eGPB2) == 0){
    Joystick[0].setButton(18, 1);
    Joystick[0].setYAxis(731);
  } else {
    Joystick[0].setButton(18, 0);
  }

  if (mcp2.digitalRead(mcp2.eGPB1) == 0){
    Joystick[0].setButton(19, 1);
    Joystick[0].setYAxis(877);
  } else {
    Joystick[0].setButton(19, 0);
  }

  if (mcp2.digitalRead(mcp2.eGPB0) == 0){
    Joystick[0].setButton(20, 1);
    Joystick[0].setYAxis(1024);
  } else {
    Joystick[0].setButton(20, 0);
  }

//Buttons for Joystick #1

  if (mcp1.digitalRead(mcp1.eGPB6) == 0){
    Joystick[1].setButton(0, 1);
  } else {
    Joystick[1].setButton(0, 0);
  }

  if (mcp1.digitalRead(mcp1.eGPB6) == 1 && mcp1.digitalRead(mcp1.eGPB7) == 1){
    Joystick[1].setButton(1, 1);
  } else {
    Joystick[1].setButton(1, 0);
  }

  if (mcp1.digitalRead(mcp1.eGPB7) == 0){
    Joystick[1].setButton(2, 1);
  } else {
    Joystick[1].setButton(2, 0);
  }

  if (mcp2.digitalRead(mcp2.eGPA4) == 0){
    Joystick[1].setButton(3, 1);
  } else {
    Joystick[1].setButton(3, 0);
  }

  Joystick[1].setButton(4, 0);  //Button 5 for Discord again






  if (mcp2.digitalRead(mcp2.eGPA4) == 1 && mcp2.digitalRead(mcp2.eGPA5) == 1){
    Joystick[1].setButton(5, 1);
  } else {
    Joystick[1].setButton(5, 0);
  }

  if (mcp2.digitalRead(mcp2.eGPA5) == 0){
    Joystick[1].setButton(6, 1);
  } else {
    Joystick[1].setButton(6, 0);
  }

  if (mcp2.digitalRead(mcp2.eGPA0) == 0){
    Joystick[1].setButton(7, 1);
    Joystick[1].setXAxis(0);
  } else {
    Joystick[1].setButton(7, 0);
  }

  if (mcp2.digitalRead(mcp2.eGPA1) == 0){
    Joystick[1].setButton(8, 1);
    Joystick[1].setXAxis(341);
  } else {
    Joystick[1].setButton(8, 0);
  }

  if (mcp2.digitalRead(mcp2.eGPA2) == 0){
    Joystick[1].setButton(9, 1);
    Joystick[1].setXAxis(682);
  } else {
    Joystick[1].setButton(9, 0);
  } 

  if (mcp2.digitalRead(mcp2.eGPA3) == 0){
    Joystick[1].setButton(10, 1);
    Joystick[1].setXAxis(1024);
  } else {
    Joystick[1].setButton(10, 0);
  } 

  if (mcp1.digitalRead(mcp1.eGPB5) == 0){
    Joystick[1].setButton(11, 1);
    Joystick[1].setYAxis(0);
  } else {
    Joystick[1].setButton(11, 0);
  }

  if (mcp1.digitalRead(mcp1.eGPB4) == 0){
    Joystick[1].setButton(12, 1);
    Joystick[1].setYAxis(341);
  } else {
    Joystick[1].setButton(12, 0);
  }

  if (mcp1.digitalRead(mcp1.eGPB3) == 0){
    Joystick[1].setButton(13, 1);
    Joystick[1].setYAxis(682);
  } else {
    Joystick[1].setButton(13, 0);
  }

    if (mcp1.digitalRead(mcp1.eGPB2) == 0){
    Joystick[1].setButton(14, 1);
    Joystick[1].setYAxis(1024);
  } else {
    Joystick[1].setButton(14, 0);
  }


  Joystick[1].setZAxis(analogRead (A0));
  Joystick[1].setRxAxis(analogRead (A1));

  if (mcp2.digitalRead(mcp2.eGPA6) == 0){
    Joystick[1].setButton(15, 1);
  } else {
    Joystick[1].setButton(15, 0);
  }

    if (mcp2.digitalRead(mcp2.eGPA6) == 1 && mcp2.digitalRead(mcp2.eGPA7) == 1){
    Joystick[1].setButton(16, 1);
  } else {
    Joystick[1].setButton(16, 0);
  }

  if (mcp2.digitalRead(mcp2.eGPA7) == 0){
    Joystick[1].setButton(17, 1);
  } else {
    Joystick[1].setButton(17, 0);
  }

  if (digitalRead(4) == 0){
    Joystick[1].setButton(18, 1);
    Joystick[1].setRyAxis(0);
  } else {
    Joystick[1].setButton(18, 0);
  }

  if (digitalRead(5) == 0){
    Joystick[1].setButton(19, 1);
    Joystick[1].setRyAxis(256);
  } else {
    Joystick[1].setButton(19, 0);
  }

  if (digitalRead(6) == 0){
    Joystick[1].setButton(20, 1);
    Joystick[1].setRyAxis(512);
  } else {
    Joystick[1].setButton(20, 0);
  }

  if (digitalRead(7) == 0){
    Joystick[1].setButton(21, 1);
    Joystick[1].setRyAxis(768);
  } else {
    Joystick[1].setButton(21, 0);
  }

  if (digitalRead(8) == 0){
    Joystick[1].setButton(22, 1);
    Joystick[1].setRyAxis(1024);
  } else {
    Joystick[1].setButton(22, 0);
  }


  // Überprüfe, ob der Button gedrückt wurde
  if (digitalRead(9) == LOW) {
    if (!buttonPressed) {
      buttonPressStartTime = millis();
      buttonPressed = true;
    }

    // Überprüfe, ob die erforderliche Zeit für den langen Druck erreicht wurde
    if (millis() - buttonPressStartTime >= requiredLongPressTime && !dimmerActivated) {
      dimmer();
      dimmerActivated = true;
    }
  } else {
    // Button nicht gedrückt
    if (buttonPressed) {
      buttonPressed = false;

      if (millis() - buttonPressStartTime >= requiredShortPressTime && !dimmerActivated) {
        button24Activated = true;
        button24StartTime = millis();
        digitalWrite(button, HIGH);
        Joystick[1].setButton(23, 1);
      }
    }

    // Check if Variable button24 auf HIGH und Zeit erreicht
    if (button24Activated && millis() - button24StartTime >= button24Duration) {
      button24Activated = false;
      digitalWrite(button, LOW);
      Joystick[1].setButton(23, 0);
    }
  }

  // Button für mehr als 5 Sekunden gedrückt dann
  if (millis() - buttonPressStartTime >= 5000 && dimmerActivated) {
    dimmerActivated = false;
  Serial.println("Dimmer-Routine beendet");
  }

  // Pin 9 LOW = Funktion manuell beenden
  if (digitalRead(9) == LOW && dimmerActivated) {
    dimmerActivated = false;

    Serial.println("Dimmer-Routine manuell beendet");
  }

  delay(10);
}

void dimmer() {
  
  Serial.println("Dimmer aufgerufen");
  analogWrite(led, 0);
  delay(60);
  analogWrite(led, 255);
  delay(60);
  analogWrite(led, 0);
  delay(60);
  analogWrite(led, 255);
  delay(60);
  analogWrite(led, 0);
  delay(60);
  analogWrite(led, 255);
  delay(60);
  analogWrite(led, 0);
  delay(60);
  analogWrite(led, ledValue);
  Start:
  
  
  if (digitalRead(9) == 0){

    float myFloat = analogRead(A0);
    PWMVal = mapFloat  (myFloat, 0,1023,0,255); // 0->0 , 10->255
    analogWrite(led, PWMVal);
    Serial.println (PWMVal);
    goto Start;
  } else {
    ledValue = PWMVal;
    EEPROM.write(0, ledValue);
  }
}

Viel Text keine Angaben. Verständlich ist das ganze auch nicht.
Arduino von gibt's Minimum 10 Sorten

Welche Informationen benötigst du?

Arduino Leonardo 32U4

Also bei Deinem PC funktioniert der Leonardo wie er soll.
Bei jemandem anderen an seinem PC nicht.

Komisch.
Informiere Dich mal welche Computer das sind und ob die Arduinos direkt oder über einen USB Hub ageschlossen sind.

Grüße Uwe

Seltsam ist halt nur, das er als Arduino erkannt wird, man ihn flashen kann und sonst keine Fehler vorhanden sind.

Es befinden sich ca. 80 LEDs in diesem Panel, welche mit einer pwm fähigen Konstantstromquelle gedimmt werden.

Es muss deswegen unbedingt an einem USB Hub mit Stromversorgung angeschlossen werden.

Aber ich denke wir dimmen diese mal auf aus und testen das Panel direkt am PC.

In meinen Augen ein Designfehler. Einmal nicht dran gedacht und schwups ist der USB Port am PC durch. Dann doch lieber eine zusätzliche Stromeinspeisung am Gerät selbst vorsehen.

Ja das wurde mit allen besprochen und ich wollte deswegen keine LEDs zur Beleuchtung haben. Wir haben eh ohnehin alle eine VR Brille auf und sehen das nicht einmal.

Zusätzliche Stromversorgung war auch nicht gewünscht.
Strombedarf ist noch im Rahmen aber powered USB Hub war meine Vorgabe um im Falle eines Fehlers nicht den PC zu grillen.

Design Fehler ist es nur, wenn es nicht ausdrücklich so gewünscht wurde.

FYI:

Auf der GitHub Seite der Joystick library habe ich Bugreports gefunden, welche unserem Burgreport ähneln.

Einer meinte das er das Problem hatte und er dann den Joystick Type änderte und es dann funktionierte.

Das Panel besteht aus so vielen Schaltern, das ein Joystick nicht ausreicht also habe ich 2 Joysticks im Code.

Der erste der beiden fehlte, diesen habe ich nun zu Gamepad geändert und nun funktioniert es.