Arduino Micro - Belegung für Simracing Wheel

Moin,

in meinem ersten Projekt mit Arduino musste ich viel googeln, lesen und verstehen wie ich all die Buttons etc. verlegen muss. Dennoch bin ich mir absolut unsicher ob ich das richtig als Diagramm gezeichnet habe.

12 Buttons
2 Paddle Shifter mit Micro Leveler "C und NO"
2 Rotary Encoder mit Button Funktion.

Das Diagramm ist im Anhang, mein erstes und hoffentlich direkt richtiges.
Ich bitte euch, dies einmal anzuschauen und mir zu sagen ob das so in Funktion geht oder ob dort Fehler in der Belegung sind.
Ich habe das ganze anhand von dem bekannten Tutorial von AMSTUDIO's Video über die Simracing Buttonbox erstellt. Das ganze nach seinem Schema, nur angepasst für meins.

Ich habe dazu noch keinen Sketch, ich denke ich müsste den von AMSTUDIO umschreiben oder gar ein neuen erstellen.

Viele Grüße
Max

solange du genud Pins hast ist jede mögliche Belegung richtig.
man kann die linke zwei Schalter auf Reihe A1 verlegen, genau so die Tasten des Encoders,
oder umgekehrt: eine Matrix 3*3 und alle andere auf frei gebliebe Pins verlegen.

/*
  button box 32 buttons with 2 rotaries and 0 axis for Arduino pro micro
*/

#include <Joystick.h>
#define enablePullUps
const byte numOfRotaries = 2;

//Creating an arrays with pins that are used
// for more info: 21 = A3, 20 = A2, 19 = A1, 18 = A0 ....
byte rowPins[] = {21, 20, 19, 18};
byte colPins[] = {16, 10, 9, 14, 15};
byte button[] = {4, 5};

struct rotariesStruct {
  byte pin1;
  byte pin2;
  byte cClockWise;
  byte clockWise;
  byte state;
} Encs[numOfRotaries] {
  {0, 1, 28, 29, 0}, //pin 0 and 1 are connected to joystick button 36, 37
  {2, 3, 30, 31, 0}
};

//define size of array
const int numOfColumns = sizeof(colPins) / sizeof(colPins[0]);
const int numOfRows = sizeof(rowPins) / sizeof(rowPins[0]);

//create and define the joystick
Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_JOYSTICK,
                   32, 0,  // not all applications supporting more as 32 buttons
                   false, false, false, //  X, Y, Z axes
                   false, false, false, //  Rx, Ry, Rz
                   false, false, //  rudder, throttle
                   false, false, false); // accelerator, break, steering

const byte RT[6][4] = {
  {0x03, 0x02, 0x01, 0x00},  // 0x0 (00)
  {0x13, 0x00, 0x01, 0x00},  // 0x1
  {0x23, 0x02, 0x00, 0x00},  // 0x2
  {0x03, 0x05, 0x04, 0x00},  // 0x3
  {0x03, 0x03, 0x04, 0x20},  // 0x4
  {0x03, 0x05, 0x03, 0x10},  // 0x5
};

void setup() {
  Joystick.begin();
  initializeRotaryEncoders();
  for (byte r = 0; r < numOfRows; r++) {
    pinMode(rowPins[r], INPUT_PULLUP);
  }
   for (byte r = 0; r < 2; r++) {
    pinMode(button[r], INPUT_PULLUP);
  }
}

void loop() {
  CheckButtons();
  CheckRotaryEncoder();
}

void CheckButtons() {
  for (byte c = 0; c < numOfColumns; c++) {
    pinMode(colPins[c], OUTPUT);
    digitalWrite(colPins[c], LOW); // Begin column pulse output.
    for (byte r = 0; r < numOfRows; r++)Joystick.setButton(2+r + c * numOfColumns, !digitalRead(rowPins[r]));
    pinMode(colPins[c], INPUT_PULLUP);
  }
  Joystick.setButton(0, !digitalRead(button[0]));
  Joystick.setButton(1, !digitalRead(button[1]));
}

void initializeRotaryEncoders() { //create and initial rotary
  for (int i = 0; i < numOfRotaries; i++) {
    pinMode(Encs[i].pin1, INPUT); //set pins to input
    pinMode(Encs[i].pin2, INPUT);
#ifdef enablePullUps
    digitalWrite(Encs[i].pin1, HIGH); //set pins value to high
    digitalWrite(Encs[i].pin2, HIGH);
#endif
  }
}

byte rotaryProcess(byte i) {
  byte pinState = (digitalRead(Encs[i].pin2) << 1) | digitalRead(Encs[i].pin1);
  Encs[i].state = RT[Encs[i].state & 0xf][pinState];
  return (Encs[i].state & 0x30);
}

void CheckRotaryEncoder() {
  for (byte i = 0; i < numOfRotaries; i++) {
    byte result = rotaryProcess(i);

    //if the rotary has been turned to left
    if (result == 0x10) {
      Joystick.setButton(Encs[i].cClockWise, 1);
      delay(20);
      Joystick.setButton(Encs[i].cClockWise, 0);
    } else

      //if the rotary is turned to the right
      if (result == 0x20) {
        Joystick.setButton(Encs[i].clockWise, 1);
        delay(20);
        Joystick.setButton(Encs[i].clockWise, 0);
      }
  }
}

Moin, danke für deine Antwort.

Also würde es mehr Sinn machen die Rotary Encoder mit auf A1 zu nehmen und dann weiter auf 10 und 9, blaue Linie?
Die restlichen Pins der Rotary Encoder können soweit dann bestehen bleiben ?

Die Micro switches würde ich gerne da lassen, da die außerhalb des Gehäuses sitzen und mir das so für mich einfacher wäre.

So wie ich es verstanden habe, würde es mit dem passenden Sketch dann laufen.
Ist das was Sie im zweiten Post geschrieben haben der Sketch zu meinem Diagramm?

Viele Grüße

genau.
sag ma, vofür braucht man Encoders im Spiel? kann mich nicht erinnern was da oft zu drücken ist.

Soll ich für den Sketch dann das Diagramm nutzen oder wie eben beschrieben die Encoder mit auf A1 packen?

Ich nutze die Rotary Encoder um die ABS sowie TC Einstellung zu schalten. Die Button Funktion zum umschalten um auf Bremsbalance umzustellen und dies dann per Rotary einzustellen.

Die Buttons sind für verschiedenste Funktionen gedacht.

wenn du so willst. dann könnte man die entsprechende Zeile ersetzen:

byte rowPins[] = {21, 20, 19};

Moin, ich Wollte den Sketch gerade hereinkopieren, Verifizieren und Uploaden.
nun sagt er mir dies, was muss oder soll ich dagegen machen?

viele grüße

Tue das mal in lesbarer Form in zeigen, nicht jeder sitzt vor 25" Monitor :wink:
Normaler weise schreib dir der Compiler wo es weh tut. Im deinem Fall sehr deutlich

Mit Windows rumgespielt und die Bibliothek zufällig gelöscht?

Moin,

Fehler gefunden, ich habe das .zip Archiv für "Joystick.h" nicht installiert.
Installiert und es geht.

Mir ist noch etwas aufgefallen, viele Buttons haben die selbe Belegung, ich denke ich weiß auch wieso.

und zwar werden die Linie wie folgt anders (nicht wie nach Diagramm), da ich diese so angeschlossen habe:
14 -> 15
16 -> 14
10 -> 16
9 -> 10
8 -> 9
so habe ich es am Board angeschlossen.
Muss es zwingen so angeschlossen sein, wie vorgegeben anfangend mit 14 endend mit 8?

Kann es daran liegen, das manche Buttons doppelt belegt sind.
Wenn ja, was muss ich ändern im Sketch damit das wieder passt?

viele grüße

mach mal neue Diagram

Ja, mache ich heute Nachmittag / Abend fertig!

genau so ist es auf der Platine auch angeschlossen.

/*
  button box 32 buttons with 2 rotaries and 0 axis for Arduino pro micro
*/

#include <Joystick.h>
#define enablePullUps
const byte numOfRotaries = 2;

//Creating an arrays with pins that are used
// for more info: 21 = A3, 20 = A2, 19 = A1, 18 = A0 ....
byte rowPins[] = {A1, A2, A3};
byte colPins[] = {15, 14, 16, 10, 9};
byte button[] = {4, 5};

struct rotariesStruct {
  byte pin1;
  byte pin2;
  byte cClockWise;
  byte clockWise;
  byte state;
} Encs[numOfRotaries] {
  {0, 1, 28, 29, 0}, //pin 0 and 1 are connected to joystick button 36, 37
  {2, 3, 30, 31, 0}
};

//define size of array
const int numOfColumns = sizeof(colPins) / sizeof(colPins[0]);
const int numOfRows = sizeof(rowPins) / sizeof(rowPins[0]);

//create and define the joystick
Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_JOYSTICK,
                   32, 0,  // not all applications supporting more as 32 buttons
                   false, false, false, //  X, Y, Z axes
                   false, false, false, //  Rx, Ry, Rz
                   false, false, //  rudder, throttle
                   false, false, false); // accelerator, break, steering

const byte RT[6][4] = {
  {0x03, 0x02, 0x01, 0x00},  // 0x0 (00)
  {0x13, 0x00, 0x01, 0x00},  // 0x1
  {0x23, 0x02, 0x00, 0x00},  // 0x2
  {0x03, 0x05, 0x04, 0x00},  // 0x3
  {0x03, 0x03, 0x04, 0x20},  // 0x4
  {0x03, 0x05, 0x03, 0x10},  // 0x5
};

void setup() {
  Joystick.begin();
  initializeRotaryEncoders();
  for (byte r = 0; r < numOfRows; r++)pinMode(rowPins[r], INPUT_PULLUP);
  for (byte r = 0; r < 2; r++)pinMode(button[r], INPUT_PULLUP);
}

void loop() {
  CheckButtons();
  CheckRotaryEncoder();
}

void CheckButtons() {
  for (byte c = 0; c < numOfColumns; c++) {
    pinMode(colPins[c], OUTPUT);
    digitalWrite(colPins[c], LOW); // Begin column pulse output.
    for (byte r = 0; r < numOfRows; r++)Joystick.setButton(r + c * numOfColumns, !digitalRead(rowPins[r]));
    pinMode(colPins[c], INPUT_PULLUP);
  }
  Joystick.setButton(0, !digitalRead(button[26]));
  Joystick.setButton(1, !digitalRead(button[27]));
}

void initializeRotaryEncoders() { //create and initial rotary
  for (int i = 0; i < numOfRotaries; i++) {
    pinMode(Encs[i].pin1, INPUT); //set pins to input
    pinMode(Encs[i].pin2, INPUT);
#ifdef enablePullUps
    digitalWrite(Encs[i].pin1, HIGH); //set pins value to high
    digitalWrite(Encs[i].pin2, HIGH);
#endif
  }
}

byte rotaryProcess(byte i) {
  byte pinState = (digitalRead(Encs[i].pin2) << 1) | digitalRead(Encs[i].pin1);
  Encs[i].state = RT[Encs[i].state & 0xf][pinState];
  return (Encs[i].state & 0x30);
}

void CheckRotaryEncoder() {
  for (byte i = 0; i < numOfRotaries; i++) {
    byte result = rotaryProcess(i);

    //if the rotary has been turned to left
    if (result == 0x10) {
      Joystick.setButton(Encs[i].cClockWise, 1);
      delay(20);
      Joystick.setButton(Encs[i].cClockWise, 0);
    } else

      //if the rotary is turned to the right
      if (result == 0x20) {
        Joystick.setButton(Encs[i].clockWise, 1);
        delay(20);
        Joystick.setButton(Encs[i].clockWise, 0);
      }
  }
}

Moin, danke für den Sketch.
Nun bildet sich folgendes ab, mehrere Tasten werden als gleichzeitig drückend angezeigt, auch wenn ich eine Taste drücke, woher kommt das und was kann ich dagegen tun?

viele grüße

unsichere Verbindungen, vermutlich, obwohl Muster der "gedrückten" Buttons sieht sehr seltsam aus

Habe nochmals die Anschlüsse an Platine und Buttons überprüft, da ist keiner ab oder halb befestigt.

Ich kann mir das nicht erklären. Kenne mich auch tatsächlich damit nicht aus, wüsste auch nicht welchen Fehler ich googeln könnte um an eine eventuelle Lösung zu kommen.

Wenn ich den falsche Sketch von oben nutze, habe ich auch eine gedrückte Fehler Belegung, nur andere Buttons.

könntest du Encoders mal raus trennen? um nur die Button Matrix zu testen

Tatsächlich ungern, da ich alle angelötet und mit schrumpfschläuchen versehen habe. :sweat_smile:
Habe auch schon überlegt einen Joystick programmiert zu nehmen, nur passt der nicht in das Case rein.

Wie würde ich denn die Fehlerquelle ermitteln können, ohne die rauszulöten?

abschneiden?