Button Matrix für Simulator

Ich will für meine Simulator eine 6x6 Matrix mit schalter und knopfen haben. Das grundlegende vom programm mit debounce und schalter habe ich alles. Ich weiß nur nicht wie ich die 36 signale an den pc leite. das bis jetzt alle tastatur tasten belegt sind müssen die signal als gamepad mit 36 button gesendet werden. Die libs die ich bis jetzt gefunden hatte, hatten nur bis 32. und HID-Project habe ich noch nicht verstanden

Der Code den ich jetzt habe scan die matrix und sendet es über serial. Die HID Commands habe ich nutzlos gemacht

//#include <HID-Project.h>

const int colPins[] = {2, 3, 4, 5, 6, 7};
const int rowPins[] = {8, 9, 10, 14, 15, 16};
const int numRows = 6;
const int numCols = 6;

uint8_t rawhidData[255];

bool isSwitchButton[numRows][numCols] = {
  {true, true, true, true, true, true},
  {true, true, true, true, true, true},
  {true, true, true, true, true, true},
  {true, true, true, true, true, true},
  {true, true, true, true, true, true},
  {true, true, true, true, true, true}
};

bool butonstate[numRows][numCols] = {0};

void setup() {
  for (int col = 0; col < numCols; col++) {
    pinMode(colPins[col], INPUT_PULLUP);
  }
  for (int row = 0; row < numRows; row++) {
    pinMode(rowPins[row], OUTPUT);
    digitalWrite(rowPins[row], HIGH);
  }
  Serial.begin(115200);
//  RawHID.begin(rawhidData, sizeof(rawhidData));
}

void loop() {
  bool SEND[36] = {0};
  byte i = 0;
  for (int col = 0; col < numCols; col++) {
    digitalWrite(rowPins[col], LOW);
    for (int row = 0; row < numRows; row++) {
      butonstate[row][col] = !digitalRead(colPins[row]);
      i = (row+1) + (col*6);
      SEND[i] = !digitalRead(colPins[row]);
    }
    digitalWrite(rowPins[col], HIGH);
  } 
for (int l = 1; l < 37; l++){
  Serial.print(SEND[l]);
}
Serial.println(" ");
delay(100);
}

In meinem aktuellen Test Aufbau sind alles schalter

Im englischen Teil des Forum müssen die Beiträge und Diskussionen in englischer Sprache verfasst werden. Deswegen wurde diese Diskussion in den deutschen Teil des Forums verschoben.

mfg ein Moderator.

Wieso PC ?
Hier bist du in einem Arduino Forum. Wenn es zum Arduino geht, da können wir helfen.
Z.B. geht das als Matrix, da brauchst du nur 12 Leitungen an einem Arduino. Dann kannst du das Ergebnis seriell an den PC schicken. Und wenn es dafür kein Library gibt, dann kannst du es doch auch selbst programmieren. Und danach sieht doch dein Sketch schon aus.

Daraus kristallkugle ich daß mehrere Schalter bzw Taster gleichzeitig geschlossen sein. Damit das funktioniert braucht man eine spezielle Variante der Matrix. Eine Normale Matrix erkennt keine 2 gleichzeitig gedrückte Taster.
Damit mehrere Kontakte als geschlossen erkannt werden könne,n muß in Reihe zu jedem Kontakt eine Diode geschaltet sein.


Beschreibung :
https://www-user.tu-chemnitz.de/~heha/Mikrocontroller/Tastenmatrix.htm

Du solltest versuchen Die richtigen Begriffe zu lernen.
Weder Butten, knopfen. Auch eine gewissesinnvolle Verwendung der deutschen Gramatik kann hilfreich sein uns das zu übermitteln, was Du sagen möchtest.

PS : I konn a Dialekt schreibn obr zem verstesch net amol es holbe.
(Übersetzung Icj kann auch Dialekt schreiben, aber dann verstehst Du nicht einmal die Hälfte.)

Grüße Uwe

Das halte ich für falsch.
Die Standard 4x4-Matrixen werden ja auch nicht so angeschlossen wie von Dir aufgemalt, sondern da bekommt ROW und COL jeweils einen PIN.
Das hat auch seine Grund.
Immer ein COL wird HIGH gezogen und auf ROW abgefragt. (oder andersrum)

Ich wurde sowas nehmen, dazu gibt auch eine Lib = keine Probleme.

Komm ich mal auf das zurück, was eigentlich die Ausgangsfrage war.

Woran scheitert es?
Vielleicht als ersten Einstieg:

@agmue ist zwar derzeit offline, aber seine Erholungszeit ist auch bald um :slight_smile: Andererseits ist das alles nicht ganz so ein Hexenwerk, wie es im ersten Moment scheint.

ok, dieser Kontroller liest bis zu 80 Tasten ein. Er übernimmt selbständig das Skanning der Matrix und braucht keine Dioden an den Tastern. Er kann zwar MEhrfachtastendrücke erkennen aber ganz so zufällige Mehrfachtastendrücke kann er auch nicht erkennen:

Aus dem Datenblatt https://www.ti.com/lit/ds/symlink/tca8418.pdf Absatz 9.1.1
"The TCA8418 supports multiple key presses accurately. Applications requiring three-key combinations (such as
< Ctrl>< Alt>< Del>, or any other combinations) must ensure that the three keys are wired in appropriate key
positions to avoid ghosting (or appearing like a 4th key has been pressed)."

Grüße Uwe

Ich sehe Deine Bedenken als unbegründet.
Ich sehe die 10kOhm Widerstände als Pullupwiderstände und die COL1 bis COL4 sind ja Pins des Controllers.
Außerdem sollte das ein Beispielschaltplan sein , wohin die Dioden geschaltet werden müssen.

Grüße Uwe

Das Aktuelle Problem ist ist das senden der daten vom Arduino an den PC. Aus siecht vom PC soll ein Gamepad mit 36 Knöpfen erkannt werden. Da die Joystick Bibliothek nur 32 will ich gerne die HID-Projekt Bibliothek benutzen. Für aktuell könnte ich die letzten 4 übrigen knöpfe auf das d-pad legen, aber das da ganze später erweiterbar sein soll würde ich es gerne anders machen.

Hallo timobi

Nimm dafür am Besten eine Arduino Due. Der stellt viele viele Portpins zur Verfügung.

Es braucht keine Dioden.
Es braucht auch keine Pullups.
Die Dinger werden genauso angeschlossen wie die 4x4 Matrixkeypads.
Dazu braucht es 12 Pins (6x6 -> 6+6) um 36 Tasten/Schalter oder Kombinationen davon abzubilden.

Ja. Darum habe ich Dir dei Anleitung von @agmue angeboten.
Du brauchst einen Controller, der

  • 12 digitale Pins hat
  • ein HID-Device sein kann

Ein UNO kann das. DerUSB-Controller wird dafür nur umprogrammiert. -> Siehe die Anleitung
(Das geht auch wieder zurück -> steht auch da)

aktuell lauft es auf einem Arduino pro Micro mit dem kann ich eine 6x6 Matrix machen und habe auch noch analoge Pins offen. da die Platine schon fertig ist, ist nur das Programm fehlend

mir hilft das zwar aber auch gleichzeitig nicht.

Das ganze soll am ende so einfach sein wie möglich (Für möglich nachbauten von unerfahrene dafür auch eine Platine mit schraubklemmen)

Und das ganze soll möglich ohne Treiber und andere Programme laufen wenn möglich (Aus gleichem Grund).

Update Habe den code so weit das es zumindest die Signale richtig an den PC sendet aber diese Version ist aktuell ohne Funktion. Bin aber noch am daran arbeiten.

#include <HID-Project.h>
#include <HID-Settings.h>


const int colPins[] = {2, 3, 4, 5, 6, 7};                       // Col Pin für matrix
const int rowPins[] = {8, 9, 10, 14, 15, 16};                   // Row Pins für matrix
const int numRows = 6;                                          // Unveränderbar
const int numCols = 6;                                          // Unveränderbar

const int debounceDelay = 50;                                   //Debounce für Knöpfe/Schalterhh

bool isSwitchButton[numRows][numCols] = {{true,  true,  true,  true,  true,  true },
                                         {true,  true,  true,  true,  true,  true },
                                         {true,  true,  true,  true,  true,  true },
                                         {true,  true,  true,  true,  true,  true },
                                         {true,  true,  true,  true,  true,  true },
                                         {true,  true,  true,  true,  true,  true }};

bool butonstatenow[numRows][numCols] = {0};
bool butonstatelast[numRows][numCols] = {0};
bool butonstate[numRows][numCols] = {0};
unsigned long lastDebounceTime[numRows][numCols];

void setup() {
  for (int col = 0; col < numCols; col++) {
    pinMode(colPins[col], INPUT_PULLUP);
  }
  for (int row = 0; row < numRows; row++) {
    pinMode(rowPins[row], OUTPUT);
    digitalWrite(rowPins[row], HIGH);
  }
  Gamepad.begin();
}

void loop() {
  memset(butonstate, 0, sizeof(butonstate));
  for (int col = 0; col < numCols; col++) {
    digitalWrite(rowPins[col], LOW);
    for (int row = 0; row < numRows; row++) {
      unsigned long currentMillis = millis();
      butonstatenow[row][col] = !digitalRead(colPins[row]);

      if (butonstatenow[row][col] != butonstatelast[row][col]) {
        lastDebounceTime[row][col] = millis();
      }
      
      
      if (isSwitchButton[row][col]){
        if((currentMillis-lastDebounceTime[row][col]) >= debounceDelay){
            if (butonstatenow[row][col] != butonstatelast[row][col]) {
            butonstatelast[row][col] = butonstatenow[row][col];
            butonstate[row][col]=HIGH;
          }
        }
      }else{
        if((currentMillis-lastDebounceTime[row][col]) >= debounceDelay) {
          if (butonstatenow[row][col] != butonstatelast[row][col]) {
            butonstatelast[row][col] = butonstatenow[row][col];
            if (butonstatenow[row][col] == LOW) {
              butonstate[row][col]=HIGH;
            }
          }
        }
      }
      if(((row) + (col*6))<=31){
        if(butonstate[row][col]){
          Gamepad.press(((row+1) + (col*6)));
        }else{
          Gamepad.releaseAll();
        }
      }else{
        byte dpad1Value = calculateDPadValue(butonstate[2][5], 0, 0, butonstate[3][5]);
        byte dpad2Value = calculateDPadValue(butonstate[4][5], 0, 0, butonstate[5][5]);

        Gamepad.dPad1(dpad1Value);
        Gamepad.dPad2(dpad2Value);
      }
    }
    digitalWrite(rowPins[col], HIGH);
  }
  
  Gamepad.write();
  delay(100);
}
int calculateDPadValue(bool up, bool down, bool left, bool right) {
  if (up && right) {
    return GAMEPAD_DPAD_UP_RIGHT;
  } else if (up && left) {
    return GAMEPAD_DPAD_UP_LEFT;
  } else if (down && right) {
    return GAMEPAD_DPAD_DOWN_RIGHT;
  } else if (down && left) {
    return GAMEPAD_DPAD_DOWN_LEFT;
  } else if (up) {
    return GAMEPAD_DPAD_UP;
  } else if (down) {
    return GAMEPAD_DPAD_DOWN;
  } else if (left) {
    return GAMEPAD_DPAD_LEFT;
  } else if (right) {
    return GAMEPAD_DPAD_RIGHT;
  } else {
    return GAMEPAD_DPAD_CENTERED;
  }
}

???
Entweder Arduino pro mini oder Arduino micro
Aber wenn Du USB-HID kannst, wird es ein pro mini sein.

Was ist jetzt Dein Problem?
Du hast doch den Ansatz schon.

Am Anfang hatte ich problem mit dem Programm. Jetzt habe ich eine gute Infos gefunden und bin selber gut vorangekommen.
Ich stehe gerne für tipp offen aber so funktioniert jetzt alles
Ich werde nur am ende meine Lösung hier reinlegen dann kann ich das hier auch als gelöst machen

Wo kommt das Gamepad her?

Den hier:

versteh ich überhaupt nicht. Was sollen die ganzen Klammern da?

Bei calcultaeDPadValue() kannst die 0,0, rausnehmen und die Funktion einstampfen, wenn das nicht gebraucht wird.
Das return GAMEPAD_DPAD_CENTERED; gehört ohne else rein.

Das sehe ich ganz kritisch! - Das haste später nochmal, wenn das zurücksetzt.

Und irgendwie glaub ich das da zuviel Code drumrum ist umd die Stati zu merken....
Du schreibst doch nur einmal auf den USB, wenn sich der Status geändert hat? richtig?
Und wozu sind die 100ms Delay da drin?

Weder noch:
"Here at SparkFun, we refuse to leave 'good enough' alone. That's why we're adding to our line-up of Arduino-compatible microcontrollers once more! The Pro Micro is similar to the Pro Mini except with an ATmega32U4 on board"
und
" Arduino Pro Micro 3,3 V / 16 MHz | ATMega32U4 | Entwicklungsboard mit mini USB | Arduino kompatibel"

Also ein Micro Nachbau mit einem anderen Layout/ Nummmer der herausgeführten Anschlüsse.
Sparkfun hatte / hat die Lizenz eigene Produkte mit dem Namen und Arduino-Logo zu verkaufen. Diese hatten immer die Bezeichnung "PRO" im Namen.
zB

Grüße Uwe