Alle Taster einer Tastenmatrix gleichzeitig abfragen und ausgeben können

Hallo.
Ich bin dabei ein Klavier mit einer Keyboardtastatur zu bauen (Derzeitige Hardware besteht aus: ESP32, SX1509, shifting microSD-Card-Modul (um später gespeicherte Lieder abspielen zu können), UDA1334A) .
Die Tastatur verfügt über 2 Flachbankkabel. Einmal mit 7 Kabelsträngen und einmal mit 8 Kabelsträngen. Dies lässt sich für mich darauf schließen, dass eine Matrix dahinter steckt.
Ich habe also diese zwei Flachbandkabel mit Hilfe eines SX1509-Moduls an meinen ESP32 verbunden (8er-Leiste von PIN 0-7 und 7er-Leiste von PIN 8-14 des SX1509).
Durch das UDA1334A Modul lasse ich den Ton auf einen JBL-Lautsprecher ausgeben.
Bisher habe ich es geschafft einen Code zu schreiben, der durch betätigen einer Taste den richten Midi-Ton dazu ausgibt. Verwenden tue ich dabei die STK-Library für die Tonausgabe mit Midi-Noten.

Jetzt zu meinem Problem: Wenn ich 2 Tasten gleichzeitig drücke spielt er abwechselnd die jeweiligen Töne und nicht gleichzeitig.

Meine Frage ist jetzt: Hat jemand schon Erfahrung mit sowas gemacht und kann mir sagen, wie ich es schaffe mehrere Tasten der Klaviatur geleichzeitig zu lesen und auszugeben?

Der schon vorhandene Code:

#include <Wire.h>
#include <SparkFunSX1509.h>
#include "AudioTools.h"
#include "StkAll.h"
#include "Moog.h"
#include "Arduino.h"
#include "Audio.h"
#include "SPI.h"
#include "SD.h"
#include "FS.h"

#define KEY_ROWS 8
#define KEY_COLS 8
#define SD_CS          5
#define SPI_MOSI      23
#define SPI_MISO      19
#define SPI_SCK       18

const byte SX1509_ADDRESS = 0x3E;
SX1509 io;
I2SStream i2s;
ArdStreamOut output(i2s, 1);
Moog moog;
Voicer voicer;
int group = 0;
float amplitude = 15;
int note = 0;

byte keyMap[KEY_ROWS][KEY_COLS] = {
  // 1   2   3   4   5   6   7   8
  { 0,  1,  2,  3,  4,  5,  6,  7}, // 1
  { 8,  9, 10, 11, 12, 13, 14, 15}, // 2
  {16, 17, 18, 19, 20, 21, 22, 23}, // 3
  {24, 25, 26, 27, 28, 29, 30, 31}, // 4
  {32, 33, 34, 35 , 36, 37, 38, 39}, // 5
  {40, 41, 42, 43, 44, 45, 46, 47}, // 6
  {48, 49, 50, 51, 52, 53, 54, 55}, // 7
  {56, 57, 58, 59, 60, 61, 62, 63}  // 8
};

byte notes_midi[64] = {
  0, 52, 44, 36, 28, 20, 12, 0,
  0, 53, 45, 37, 29, 21, 13, 0,
  0, 54, 46, 38, 30, 22, 14, 0,
  0, 55, 47, 39, 31, 23, 15, 0,
  0, 56, 48, 40, 32, 24, 16, 0,
  0, 57, 49, 41, 33, 25, 17, 0,
  0, 58, 50, 42, 34, 26, 18, 0,
  0, 59, 51, 43, 35, 27, 19, 0
};

void setup() {
  Serial.begin(115200);

  voicer.addInstrument(&moog, group);

  while (!Serial);
  Serial.println("Setup-Start");
  Serial.println("SX1509 keypad tone");

  Wire.begin();
  Serial.println("Wire.begin() done");

  if (io.begin(SX1509_ADDRESS) == false) {
    Serial.println("Failed to communicate. Check wiring and address of SX1509.");
    Serial.print(SX1509_ADDRESS);
    while (1);
  }

  auto cfg = i2s.defaultConfig(TX_MODE);
  cfg.bits_per_sample = 16;
  cfg.sample_rate = Stk::sampleRate();
  cfg.channels = 1;
  cfg.pin_bck = 27;   //#define I2S_BCLK  27
  cfg.pin_ws = 26;    //#define I2S_LRC   26
  cfg.pin_data = 25;  //#define I2S_DOUT  25
  i2s.begin(cfg);

  unsigned int sleepTime = 256;
  byte scanTime = 50;
  byte debounceTime = 25;
  io.keypad(KEY_ROWS, KEY_COLS, sleepTime, scanTime, debounceTime);

  long endTime = millis() + 1000;
  voicer.noteOn(90, amplitude, group);
  while (millis() + 2000 < endTime) {
    output.tick(voicer.tick());
  }
}

void loop() {
  unsigned long startTime = micros();
  unsigned int keyData = io.readKeypad();
  unsigned long endTimeMicros = micros();

  long endTime = millis() + 500;
  if (keyData != 0) {
    Serial.print("Time taken: ");
    Serial.print(endTimeMicros - startTime);
    Serial.println(" microseconds");
    byte row = io.getRow(keyData);
    byte col = io.getCol(keyData);
    byte key = keyMap[row][col];

    if (key >= 0 && key < 64) {
      note = notes_midi[key];
      Serial.println(notes_midi[key]);
      moog.noteOn(note, amplitude);
      while (millis() < endTime) {
        output.tick(moog.tick());
      }
    }
  }
}

Bei Unklarheiten gerne fragen.
Ich freue mich auf weiterbringende Antworten.

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.

Gleichzeitig betätigte Tasten einer Matrix müssen pro Taste mit einer Diode entkoppelt werden.

Gruß Tommy

Da taucht bei mir die Frage auf welche Polyphonie du hast. Denn bei einer einfachen wäre dieses verhalten normal.

Tut mir Leid, dass ich dies nicht erwähnt habe. Es sind bereits Dioden für jede Taste vorhanden.

Was meinst du damit? Ich möchte polyphonisches Spielen hinbekommen.
Was ist eine einfache Polyphonie?

Es kann nur zur Zeit ein Ton dargestellt werden. Schau in des Datenblatt zum UDA1334 . Und Goggle mal nach Polyphonie

Der UDA1334 ist ein DAC der ist weder Mono noch Poliphon.
Das Problem könnte dennoch ein Problem der Polyphonie sein aber an einer anderen Stelle; nicht am DAC.

Grüße Uwe

Wenn du das meinst: Die Klaviatur konnte vor dem Ausbau viele Tasten auf einmal. Also im Originalzustand

Hättest du eine spontane Idee?

Was machen diese Zeilen?
Grüße Uwe

Bist du sicher das die KEY-Libs auch doppelte Tasten (= 2 gleichzeitig gedrückt) meldet.

Ich persönlich würde für dieses Problem eine MCP23017 einsetzen.

Da kann ich dann prüfen ob mehr als 1 Pin high ist, und darauf reagieren.

Ist aber nur eine Idee bzw. Vorschlag.

Gruß

Pucki

Geben an, wie lange ein Tastendruck einen Ton ausgibt.

Ich schau mal nach. Das weiß ich gerade nicht

Ich auch nicht deshalb die Frage.

Soweit ich die Libs kenne liefert sie nur die gedrückte Taste (vermutlich sogar soft-Entprellt
zurück).

Dann wäre dein Problem ein Grundsätzliches Problem mit der Libs.

Gruß

Pucki

Ja, dessen bin ich mir auch gestern noch bewusst geworden. Hatte mal ein wenig geschaut und das hier entdeckt.

Diese Programmierung läßt nur einen Tastendruck zu. Es werden keine Mehrfachtastendrücke ausgewertet.
Jede Messung der gedrückten Tasten muß ein array an gedrückten Tasten zurückgegeben und dann aus jeder Taste einen Ton generiert. Wenn 2 Pianist vor der Tastatur sitzt sind konstruktionsbedingt nur 10 Tasten gleichzeitig möglich (1 Finger = 1 Taste).
Bei einem 4 Hand Spiel sind es max 20 Tastendrücke.

Programmier mal die Tastenauslesen mit Mehrfachdruck-erkennung. Die Tastaturmatrix ist ja dazu vorbereitet.

Grüße Uwe

1 Like

Ja, nebenbei, aber hauptsächlich blockieren sie den Sketch solange der Ton ausgegeben wird.

1 Like

Ok.

Schau dir DAS Video von den Type mal genau an, jedenfalls die ersten 3 Minuten OHNE TON das Gepiepse nervt.

Da schreibt er. Ich benutze eine Spezielle KEY-MAPS .

Im "Beschreibungs-Bereich" ist ein Link zu Githubs. Da ziehe dir mal zu den TOOLS das passende Beispiel rein. Dann wirst du verstehen wie das funktionieren sollte.

Wäre jedenfalls meine IDEE.

Aber Warnung: In den Video benutzt er eine PC-Tastatur. Die haben ALLE ein eigenen Chip der der Matrix ausliest und das Ergebnis sendet. Inkl. Erweiterten Key-Code. In den wird Festgelegt ob du eine der Umschalttasten benutzt hast.

Gruß

Pucki

1 Like

Das kann man aber kinderleicht lösen. Hilft aber nicht gegen den "2 - Tastendruck " den der TO will.

Gruß

Pucki

Ist aber der erste Schritt um mehrere Töne gleichzeitig zu ermöglichen.

Also:
mehrere Tasten gedrückt
Erkennung mehrerer Tasten
Generieren des Tones für jeden Tastendrucks
Grüße Uwe

Nicht mit diese Libs.

Man nehme :

1 16 Port- Port-Expander z.b. MCP23017
Dann klemme man die Matrix richtig an die Pins.

Nun frage ich an wo bei A-Reihe der Wert auf High liegt (=Taste gedrückt)
Das selbe bei Reihe B

Dann können ruhig mal 2 Tasten getroffen sein.

Die Finde ich mit der Abfrage und muss nur drauf reagieren.

Gruß

Pucki

Nicht notwendigerweise.
Auch der SX1509 kann als reiner IO Expander verwendet werden. Nur wird man da nicht die "keypad scanning engine (Ex : RegKeyConfig = 0x7D)" verwenden können und darum selber die Tastaturabfrage programmieren müssen.

"The SX1507, SX1508 and SX1509 are complete ... General Purpose parallel
Input/Output (GPIO) expander"

Die keypad scanning engine kann prinzipiell schon mehrere Tastenabfragen meistern.
Im Datenblatt steht: "This implementation allows the host to handle both single and multi-touches easily (fast AAAAAA sequence is a
long press of key A, fast ABABABAB sequence is key A and key B pressed together, etc)"
Wie das die Bibliothek macht und inwieweit das mit 10 Tasten funktioniert mag ich nicht wissen.

Grüße Uwe