4051 Multiplexer für mehr digitale Eingänge

Hallo zusammen,

Ich habe mit 6 4051 Multiplexern die Digitalen Inputs an meinem Arduino Mega erweitert. Ich möchte dort insgesamt 60 Taster anschließen und damit Midi-Noten verschicken.

Mein Problem ist, dass wenn ich einen der Taster drücke nichts passiert.

Hier ist mein Code:

int controlChange = 176; //Midikanal 1
byte controllerNummer[] =  {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80};

byte controllerWert[] =    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
byte controllerWertAlt[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
byte faderWert[] =         {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
// byte smoothWert[] =     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

int taste[] = {LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW};
int tasteAlt[] = {LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW};
boolean tasteGedrueckt[] = {false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false};

int faderPin[] = {A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14};
int tastePin[] = {30,31,32,33,34,35,36};

byte bit1 = 0;
byte bit2 = 0;
byte bit3 = 0;

int i = 0;

void setup() {
  Serial.begin(9600);
  
  //Select Pins 4051
  pinMode(22, OUTPUT);
  pinMode(23, OUTPUT);
  pinMode(24, OUTPUT);

  //Input Pins 4051 Buttons
  pinMode(30, INPUT);
  pinMode(31, INPUT);
  pinMode(32, INPUT);
  pinMode(33, INPUT);
  pinMode(34, INPUT);
  pinMode(35, INPUT);
  pinMode(36, INPUT);
}

void loop() {

  //Durchschalten der 4051
  for(int i = 0; i <= 60; i++){
    bit1 = bitRead(i,0);
    bit2 = bitRead(i,1);
    bit3 = bitRead(i,2);

     digitalWrite(22, bit1);
     digitalWrite(23, bit2);
     digitalWrite(24, bit3);

     tasteAbfragen(i,30,controllerNummer[16]);
     tasteAbfragen(i+8,31, controllerNummer[24]);
     tasteAbfragen(i+16,32, controllerNummer[32]);
     tasteAbfragen(i+24,33, controllerNummer[40]);
     tasteAbfragen(i+32,34, controllerNummer[48]);
     tasteAbfragen(i+40,35, controllerNummer[56]);
  }
  
  //Fader abfragen
  for(i = 0; i < 14; i++){
    faderWert[i] = analogRead(faderPin[i]);
    controllerWert[i] = map(faderWert[i], 0, 1023, 0, 127);
    faderWert[i] = 0.2 * faderWert[i] + 0.8 * analogRead(faderPin);

    if(controllerWertAlt[i] != controllerWert[i]){
      Serial.write(controlChange);
      Serial.write(controllerNummer[i]);
      Serial.write(controllerWert[i]);
    }
  controllerWertAlt[i] = controllerWert[i];
  }
 // smoothWert = 0.6 * smoothWert + 0.4 * analogRead(faderPin[i]);

}

//Tasten abfragen
void tasteAbfragen(int zaehler, int digitalPin, int ctrlNummer){
   taste[zaehler] = digitalRead(digitalPin);
   if(taste[zaehler] == HIGH && tasteAlt[zaehler] == LOW){
      sendeMIDI(controlChange, ctrlNummer, 127);
      tasteAlt[zaehler] = taste[zaehler];
   }
   if(taste[zaehler] == LOW && tasteAlt[zaehler] == HIGH){
      sendeMIDI(controlChange, ctrlNummer, 0);
      taste[zaehler] = taste[zaehler];
   }
}

//Midi Senden
void sendeMIDI(byte statusByte, byte dataByte1, byte dataByte2){
  Serial.write(statusByte);
  Serial.write(dataByte1);
  Serial.write(dataByte2);
}

Setze Deinen Code bitte in Codetags (</>-Button oben links im Forumseditor oder [code] davor und [/code] dahinter ohne *).
Dann ist er auch auf mobilen Geräten besser lesbar.
Das kannst Du auch noch nachträglich ändern.

Außerdem entferne bitte die unnötigen Leerzeilen und formatiere den Code ordentlich (+T in der IDE hilft Dir dabei).

Gruß Tommy

Vielleicht mußt Du die Tasten nur länger drücken?

Hast Du schon mal ausgeben lassen, wie oft loop() pro Sekunde durchlaufen wird?

Deine Idee ist originell, aber IMO viel zu langsam für so viele Tasten. Und wieso extra Multiplexer, der Mega hat doch ausreichend digitale Eingänge?

Ich würde jedenfalls eine Matrix aufbauen, die sich blitzschnell abfragen läßt.

Vielen Dank für die schnelle Antwort!

Die Tasten hab ich schon länger gedrückt. Hat aber leider nichts geholfen.

Nein das habe ich bisher noch nicht ausgeben lassen, weiß aber leider auch nicht genau wie das geht.

Der Mega hat doch nur 53 digitale Eingänge? (Auf die 16 Analogeingänge lege ich noch Fader)

Die Idee mit der Matrix klingt gut. Leider weiß ich nicht wie ich eine baue.(Bin noch ein blutiger Anfänger)

Du musst globale Variablen nicht mit 0/LOW initialisieren. Das wird automatisch gemacht. Nur lokale, nicht-statische Variablen müssen initialisiert werden

Ich würde den Arrays eine feste Länge geben, dann kann man sich auch nicht bei der (überflüssigen) Initialisierung vertun.

Tasten Matrix o.ä. läßt sich im Forum finden.

Hi

Es gibt Port-Expander für I²C - dort hast Du 8 oder 16 I/O und kannst mehrere dieser Expander gleichzeitig am Bus betreiben.
Diese haben einen Interrupt-Pin, Der bei Wechsel eines der Pegel den Zustand ändert - diesen INT-Pin fragst Du in Deinem Sketch ab.
Wenn sich hier was ändert, hat sich auf DIESEM Expander was geändert - dann fragst Du Diesen ab und hast die aktuell gedrückte Taste.

Es gibt die Expander unter mehreren I²C-IDs - Diese kann man ebenfalls mischen, wenn man mit den 4 möglichen gleichen Bausteinen nicht hin kommt, nimmt man halt Andere dazu.
Alternativ einen I²C-Multiplexer, um an die verschiedenen ICs dran zu kommen.

So brauchst Du nur 2+n Pins (SDA/SCL + je IC einen Pin für den INT).

Hat allerdings rein gar Nichts mit Deinem Versuch mit den 4051er zu tun - wäre aber mein Weg.

MfG

Alles klar, danke!

Wäre das zum beispiel ein solcher I2C Port Expander und wie frage ich diesen dann in meinem Sketch ab?

Und gibt es auch noch eine Lösung mit den 4051er?

Hi

Ja, Das wäre 'so Einer'.
Bis zu 8 davon kannst Du an einen Bus hängen (A0...A2 = 8 mögliche Kombinationen).
Die ID ist 0x20...0x27 (als 7-Bit)
Reichelt verlinkt auch das Datenblatt, deshalb hier nur die URL

Dann Suchen, ob Arduino bereits eine Lib zu diesem Typ bereit stellt (alles Andere würde mich wundern).
Dann: Spielen

MfG

Edit
Den 7 Bit noch ein 'als' spendiert - I²C-IDs werden zumeist als 7Bit dargestellt, kommt aber auch als 8Bit vor - dann müsste die ID 0x40 ... 0x4E heißen (LSB=R/W-Bit auf 0)

postmaster-ino:
Die ID ist 0x20...0x27 (7-Bit)

Falsch in 2 Richtungen:

  1. 7 Bit wären 128 verschiedene Werte
  2. 0x20...0x27 sind 8 verschiedene Werte

Gruß Tommy

Hi

Die ID (in 7 Bit Darstellung) wäre 0x20...0x27.
Bei 3 Adress-Bits (A0...A2) rechne ich fest mit 8 verschiedenen Adressen.

MfG

Hey Tommy, bitte verunsichere die Newbies nicht mit Falschinterpretationen völlig korrekter Informationen, Du disqualifizierst Dich damit nur selbst.

Danke

Sorry, aber ich habe die Aussagen so als Fehler interpretiert.

Gruß Tommy