Hilfe bei Arduino MIDI

Hallo Forumsgemeinschaft , ich habe mir auf Basis von :e-licktronic MIDI System compatible with Arduino eine Platine mit je 3 CD4021 zur Eingabe und 3 Stueck 595 Schieberegistern zur Ausgabe an LED-s gebaut . Leider bin ich absoluter Anfaenger in Sachen Arduino . Die Steuerung funktioniert auch , es werden die Taster abgefragt und deren Schaltzustand auch von den LED-s angezeigt , nur bekomme ich nichts auf MIDI ausgegeben .Wie koennte ich dieses pruefen , wenn ich im Serial Monitor die Ausgabe anschaue bekomme ich bei Tastendruck nur Quadrate ausgegeben , muesste unter Umstaenden etwas anderes angezeigt werden ?

//****************************************************************//
//    Dilicktal_MIDI v1_0	                                  //
//                                                                //
// Ce sketch montre comment utiliser la platine Dilicktal         // 
// pour envoyer des messages MIDI avec les boutons et afficher l' //
// état du bouton sur la led correspondante.                      //
//                                                                //
// Les boutons sont en mode TOGGLE ce qui signifie que lors de la //
// première pression on envoie ON en MIDI (127) et le bouton      //
// reste ON jusqu'à la deuxième pression du bouton.               //
//                                                                //
// Les fonctions shiftOut et shiftIn utilisées dans ce sketch     //
// viennent des tutoriaux présents sur le site Arduino             //
// http://www.arduino.cc/en/Tutorial/ShiftIn                      //
// http://arduino.cc/en/Tutorial/ShiftOut                         //
//****************************************************************

//Nombre de platines Dilicktal connectées (de 1 à 8   bei mir sind es 3)
#define numDigital 3

//Définir les PINs des 4021
#define latchPinIn  10
#define dataPinIn   11
#define clockPinIn  9

//Définir les PINs des 74hc595
#define latchPinOut 12
#define clockPinOut 9
#define dataPinOut  13


byte preBoutonRead[numDigital] = {
  0};//flag de la valeur de chaques boutons
byte led[numDigital] = {
  0};//valeur envoyer à chaques platines Dilicktal
byte stateBouton[numDigital] = {
  0};//état de chaques boutons
boolean stateLed[numDigital][8]={
  0};//état de chaques leds
byte boutonCC[]={
  20,28,36,44,52,60,68,76};// numéro du control change pour chaques Dilicktal
  // la valeur 20 correspond à la première platine Dilicktal connectée
  // c'est à dire que les boutons de la première platine auront les valeurs de CC de 20 à 27
  // la valeur 28 correspond à la deuxième platine Dilicktal connectée ...

void setup() {
  //Serial baud rate à 57600 pour utiliser en USB et 31250 pour utiliser en MIDI
  Serial.begin(31250);

  //define pin modes
  pinMode(latchPinIn, OUTPUT);
  pinMode(clockPinIn, OUTPUT); 
  pinMode(dataPinIn, INPUT);
  pinMode(latchPinOut, OUTPUT);

  SendToLed (255,255,255,255,255,255,255,255);
  delay (1000);
  SendToLed (0,0,0,0,0,0,0,0);
}

void loop() {

  for (int y=0; y<numDigital; y++){
    //loop autant de fois que de nombre de Dilicktal connectée
    preBoutonRead[y] = BoutonRead(y);
    // Récupère la valeur actuelle de l'octet des boutons correspondante à la platine Dilicktal
    if (stateBouton[y] != preBoutonRead[y]){
      // la valeur de l'octet des boutons a t-elle changée?
      stateBouton[y] = preBoutonRead[y];
      // Stock la valeur de l'octet changée
      for (int x =0; x <8; x++){
        //scan les 8 bits de l'octet
        if (bitRead (preBoutonRead[y], x)){
          //teste chaques boutons 
          if (stateLed[y][x]==0){
            //si la led correspondante au bouton est à 0
            bitSet (led[y],x);
            // on la met a 1
            stateLed[y][x]=1;
            // on met à jour l'état de la led
            sendCC ((x+boutonCC[y]),127);
            //On envoie le message MIDI Control Change "ON" correspondant sur le canal choisi
          }
          else{
            // mais si la led correspondante au bouton est à 1
            bitWrite (led[y],x,0);
            // On la met à 0
            stateLed[y][x]=0;
            // On met à jour l'état de la led
            sendCC ((x+boutonCC[y]),0);
            //On envoie le message MIDI Control Change "OFF" correspondant sur le canal choisi
          }
        }
      }
      SendToLed (led[0],led[1],led[2],led[3],led[4],led[5],led[6],led[7]);
      //Envoie des 8 octets correspondant aux leds
    }
  }
}

///////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////FONCTION//////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////

void SendToLed (byte data1,byte data2,byte data3,byte data4,byte data5,byte data6,byte data7,byte data8) {

  digitalWrite(latchPinOut, 0);
  delayMicroseconds(20);
  shiftOut(dataPinOut, clockPinOut, data8);  
  shiftOut(dataPinOut, clockPinOut, data7);  
  shiftOut(dataPinOut, clockPinOut, data6);
  shiftOut(dataPinOut, clockPinOut, data5);
  shiftOut(dataPinOut, clockPinOut, data4);  
  shiftOut(dataPinOut, clockPinOut, data3);  
  shiftOut(dataPinOut, clockPinOut, data2);
  shiftOut(dataPinOut, clockPinOut, data1);
  digitalWrite(latchPinOut, 1);
}

byte BoutonRead (int flag) {

  if (flag ==0){
    int i;
    digitalWrite(latchPinIn,1);
    delayMicroseconds(20);
    digitalWrite(latchPinIn,0);
    i = shiftIn(dataPinIn, clockPinIn);
    return i;
  }
  if (flag ==1){
    int i;
    digitalWrite(latchPinIn,1);
    delayMicroseconds(20);
    digitalWrite(latchPinIn,0);
    shiftIn(dataPinIn, clockPinIn);
    i = shiftIn(dataPinIn, clockPinIn); 
    return i;
  }
  if (flag ==2){
    int i;
    digitalWrite(latchPinIn,1);
    delayMicroseconds(20);
    digitalWrite(latchPinIn,0);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    i = shiftIn(dataPinIn, clockPinIn);
    return i;
  }
  if (flag ==3){
    int i;
    digitalWrite(latchPinIn,1);
    delayMicroseconds(20);
    digitalWrite(latchPinIn,0);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    i = shiftIn(dataPinIn, clockPinIn);// on stock les deux octets dans une variable  
    return i;
  }
  if (flag ==4){
    int i;
    digitalWrite(latchPinIn,1);// On met le 4021 en mode lecture
    delayMicroseconds(20);
    digitalWrite(latchPinIn,0);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    i = shiftIn(dataPinIn, clockPinIn);
    return i;
  }
  if (flag ==5){
    int i;
    digitalWrite(latchPinIn,1);
    delayMicroseconds(20);
    digitalWrite(latchPinIn,0);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    i = shiftIn(dataPinIn, clockPinIn);
    return i;
  }
  if (flag ==6){
    int i;
    digitalWrite(latchPinIn,1);
    delayMicroseconds(20);
    digitalWrite(latchPinIn,0);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    i = shiftIn(dataPinIn, clockPinIn);
    return i;
  }
  if (flag ==7){
    int i;
    digitalWrite(latchPinIn,1);
    delayMicroseconds(20);
    digitalWrite(latchPinIn,0);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    i = shiftIn(dataPinIn, clockPinIn);
    return i;
  }
}

void shiftOut(int myDataPin, int myClockPin, byte myDataOut) {

  int i=0;
  int pinState;
  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, OUTPUT);

  digitalWrite(myDataPin, 0);
  digitalWrite(myClockPin, 0);

  for (i=7; i>=0; i--)  {
    digitalWrite(myClockPin, 0);
    if ( myDataOut & (1<<i) ) {
      pinState= 1;
    }
    else {	
      pinState= 0;
    }

    digitalWrite(myDataPin, pinState);
    digitalWrite(myClockPin, 1);
    digitalWrite(myDataPin, 0);
  }
}

byte shiftIn(int myDataPin, int myClockPin) { 
  int i;
  int temp = 0;
  int pinState;
  byte myDataIn = 0;

  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, INPUT);

  for (i=7; i>=0; i--)
  {
    digitalWrite(myClockPin, 0);
    delayMicroseconds(2);
    temp = digitalRead(myDataPin);
    if (temp) {
      pinState = 1;
      myDataIn = myDataIn | (1 << i);
    }
    else {
      pinState = 0;
    }
    digitalWrite(myClockPin, 1);
  }
  return myDataIn;
}


void sendCC (int CCnum, int value)
{
  Serial.write (0xB0);//Message "control change" sur canal MIDI 1
  Serial.write (CCnum);
  Serial.write (value);
}

Vielen Dank !

Wenn Du die Funktion sendCC() am Ende des Codes meinst:
Da sind "Quadrate" aus zwei Gründen nicht ungewöhnlich:

  1. Du hast die Baudrate nicht auf 57600 (oder höher) umgestellt (siehe setup() erste Zeile)
  2. Es werden binäre Werte ausgegeben; wenn die nicht druckbar sind, gibt es Kuddelmuddel.

Versuch mal

void sendCC (int CCnum, int value)
{
  // Serial.write (0xB0);//Message "control change" sur canal MIDI 1
  // Serial.write (CCnum);
  // Serial.write (value);
  Serial.print (0xB0, HEX);  
  Serial.print(' ');
  Serial.print (CCnum, HEX);
  Serial.print(' ');
  Serial.println (value, HEX);
}

Danke , nach meiner Meinung scheint es zu funktionieren , es wird " B0 14 0 bei AUS und B0 14 7F bei EIN " bei druecken des ersten Tasters ausgegeben es scheint dann in Ordnung zu sein .Der Wert in der Mitte nimmt je nach gedrueckten Taster Werte von 14 bis 2B an.Muesste nicht auch der erste Wert Serial.print (0xB0, HEX); jeweils nach Tastendruck etwas anderes als nur B0 ausgeben ?

Ich moechte den im ersten Beitrag angehaengten code auf einen Arduino Leonardo portieren und die MIDI Ausgabe direkt per USB machen . Ich habe einige code -Schnipsel dafuer eingefuegt und die pins an den Leonardo angepasst , die Taster und LED-s funktionieren auch wie sie sollen , aber fuer den Rest brauche ich Eure Hilfe , da ich wie schon vorhin gesagt Anfaenger bin . Danke !

//****************************************************************//
//    Dilicktal_MIDI v1_0	                                  //
//                                                                //
// Ce sketch montre comment utiliser la platine Dilicktal         // 
// pour envoyer des messages MIDI avec les boutons et afficher l' //
// état du bouton sur la led correspondante.                      //
//                                                                //
// Les boutons sont en mode TOGGLE ce qui signifie que lors de la //
// première pression on envoie ON en MIDI (127) et le bouton      //
// reste ON jusqu'à la deuxième pression du bouton.               //
//                                                                //
// Les fonctions shiftOut et shiftIn utilisées dans ce sketch     //
// viennent des tutoriaux présents sur le site Arduino             //
// http://www.arduino.cc/en/Tutorial/ShiftIn                      //
// http://arduino.cc/en/Tutorial/ShiftOut                         //
//****************************************************************
#include <MIDIUSB.h>
//Nombre de platines Dilicktal connectées (de 1 à 8  bei mir sind es 3)
#define numDigital 3

//Définir les PINs des 4021
#define latchPinIn  3
#define dataPinIn   4
#define clockPinIn  2

//Définir les PINs des 74hc595
#define latchPinOut 5
#define clockPinOut 2
#define dataPinOut  6


byte preBoutonRead[numDigital] = {
  0};//flag de la valeur de chaques boutons
byte led[numDigital] = {
  0};//valeur envoyer à chaques platines Dilicktal
byte stateBouton[numDigital] = {
  0};//état de chaques boutons
boolean stateLed[numDigital][8]={
  0};//état de chaques leds
byte boutonCC[]={
  20,28,36,};// numéro du control change pour chaques Dilicktal
  // la valeur 20 correspond à la première platine Dilicktal connectée
  // c'est à dire que les boutons de la première platine auront les valeurs de CC de 20 à 27
  // la valeur 28 correspond à la deuxième platine Dilicktal connectée ...

void setup() {
  //Serial.begin(57600);
 
  MidiUSB.flush(); // Initialize the MIDIUSB library
  //define pin modes
  pinMode(latchPinIn, OUTPUT);
  pinMode(clockPinIn, OUTPUT); 
  pinMode(dataPinIn, INPUT);
  pinMode(latchPinOut, OUTPUT);

  SendToLed (255,255,255,255,255,255,255,255);
  delay (1000);
  SendToLed (0,0,0,0,0,0,0,0);
}

void loop() {

  for (int y=0; y<numDigital; y++){
    //loop autant de fois que de nombre de Dilicktal connectée
    preBoutonRead[y] = BoutonRead(y);
    // Récupère la valeur actuelle de l'octet des boutons correspondante à la platine Dilicktal
    if (stateBouton[y] != preBoutonRead[y]){
      // la valeur de l'octet des boutons a t-elle changée?
      stateBouton[y] = preBoutonRead[y];
      // Stock la valeur de l'octet changée
      for (int x =0; x <8; x++){
        //scan les 8 bits de l'octet
        if (bitRead (preBoutonRead[y], x)){
          //teste chaques boutons 
          if (stateLed[y][x]==0){
            //si la led correspondante au bouton est à 0
            bitSet (led[y],x);
            // on la met a 1
            stateLed[y][x]=1;
            // on met à jour l'état de la led
           sendCC ((x+boutonCC[y]),127);      
           midiEventPacket_t noteOn = {((x+boutonCC[y]),127)}; // MIDI note-on message
        MidiUSB.sendMIDI(noteOn); // Send MIDI message
            //On envoie le message MIDI Control Change "ON" correspondant sur le canal choisi
        //    delay(50); // Debouncing delay
          }
          else{
            // mais si la led correspondante au bouton est à 1
            bitWrite (led[y],x,0);
            // On la met à 0
            stateLed[y][x]=0;
            // On met à jour l'état de la led
              sendCC ((x+boutonCC[y]),0);
         midiEventPacket_t noteOff = {((x+boutonCC[y]),0)}; // MIDI note-off message
     MidiUSB.sendMIDI(noteOff); // Send MIDI message
            //On envoie le message MIDI Control Change "OFF" correspondant sur le canal choisi
          }
        }
      }
      SendToLed (led[0],led[1],led[2],led[3],led[4],led[5],led[6],led[7]);
      //Envoie des 8 octets correspondant aux leds
    }
  }
}

///////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////FONCTION//////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////

void SendToLed (byte data1,byte data2,byte data3,byte data4,byte data5,byte data6,byte data7,byte data8) {

  digitalWrite(latchPinOut, 0);
  delayMicroseconds(20);
  shiftOut(dataPinOut, clockPinOut, data8);  
  shiftOut(dataPinOut, clockPinOut, data7);  
  shiftOut(dataPinOut, clockPinOut, data6);
  shiftOut(dataPinOut, clockPinOut, data5);
  shiftOut(dataPinOut, clockPinOut, data4);  
  shiftOut(dataPinOut, clockPinOut, data3);  
  shiftOut(dataPinOut, clockPinOut, data2);
  shiftOut(dataPinOut, clockPinOut, data1);
  digitalWrite(latchPinOut, 1);
}

byte BoutonRead (int flag) {

  if (flag ==0){
    int i;
    digitalWrite(latchPinIn,1);
    delayMicroseconds(20);
    digitalWrite(latchPinIn,0);
    i = shiftIn(dataPinIn, clockPinIn);
    return i;
  }
  if (flag ==1){
    int i;
    digitalWrite(latchPinIn,1);
    delayMicroseconds(20);
    digitalWrite(latchPinIn,0);
    shiftIn(dataPinIn, clockPinIn);
    i = shiftIn(dataPinIn, clockPinIn); 
    return i;
  }
  if (flag ==2){
    int i;
    digitalWrite(latchPinIn,1);
    delayMicroseconds(20);
    digitalWrite(latchPinIn,0);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    i = shiftIn(dataPinIn, clockPinIn);
    return i;
  }
  if (flag ==3){
    int i;
    digitalWrite(latchPinIn,1);
    delayMicroseconds(20);
    digitalWrite(latchPinIn,0);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    i = shiftIn(dataPinIn, clockPinIn);// on stock les deux octets dans une variable  
    return i;
  }
  if (flag ==4){
    int i;
    digitalWrite(latchPinIn,1);// On met le 4021 en mode lecture
    delayMicroseconds(20);
    digitalWrite(latchPinIn,0);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    i = shiftIn(dataPinIn, clockPinIn);
    return i;
  }
  if (flag ==5){
    int i;
    digitalWrite(latchPinIn,1);
    delayMicroseconds(20);
    digitalWrite(latchPinIn,0);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    i = shiftIn(dataPinIn, clockPinIn);
    return i;
  }
  if (flag ==6){
    int i;
    digitalWrite(latchPinIn,1);
    delayMicroseconds(20);
    digitalWrite(latchPinIn,0);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    i = shiftIn(dataPinIn, clockPinIn);
    return i;
  }
  if (flag ==7){
    int i;
    digitalWrite(latchPinIn,1);
    delayMicroseconds(20);
    digitalWrite(latchPinIn,0);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    shiftIn(dataPinIn, clockPinIn);
    i = shiftIn(dataPinIn, clockPinIn);
    return i;
  }
}

void shiftOut(int myDataPin, int myClockPin, byte myDataOut) {

  int i=0;
  int pinState;
  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, OUTPUT);

  digitalWrite(myDataPin, 0);
  digitalWrite(myClockPin, 0);

  for (i=7; i>=0; i--)  {
    digitalWrite(myClockPin, 0);
    if ( myDataOut & (1<<i) ) {
      pinState= 1;
    }
    else {	
      pinState= 0;
    }

    digitalWrite(myDataPin, pinState);
    digitalWrite(myClockPin, 1);
    digitalWrite(myDataPin, 0);
  }
}

byte shiftIn(int myDataPin, int myClockPin) { 
  int i;
  int temp = 0;
  int pinState;
  byte myDataIn = 0;

  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, INPUT);

  for (i=7; i>=0; i--)
  {
    digitalWrite(myClockPin, 0);
    delayMicroseconds(2);
    temp = digitalRead(myDataPin);
    if (temp) {
      pinState = 1;
      myDataIn = myDataIn | (1 << i);
    }
    else {
      pinState = 0;
    }
    digitalWrite(myClockPin, 1);
  }
  return myDataIn;
}


void sendCC (int CCnum,int value )
{
 //Serial.write (0xB0);//Message "control change" sur canal MIDI 1
 // Serial.write (CCnum);
 // Serial.write (value); 
}
  void noteOn(int CCnum) {
  MidiUSB.sendMIDI({0x09, 0x90,CCnum, 127});
  MidiUSB.flush();
}

void noteOff(int CCnum) {
  MidiUSB.sendMIDI({0x08, 0x80,CCnum , 0});
  MidiUSB.flush();
}
  

Was ist das jetzt für ein Code?
Was sind das für französische Kommentare?

Der Code kompiliert, gibt aber Warnungen aus und gehört gesäubert.
Da werden Variablen definiert, aber nicht genutzt, bzw. angelegt, beschrieben und dann doch verworfen.
Zudem ist mir noch nicht klar, was das mit den Shiftregistern wird.

Und der hier:
midiEventPacket_t noteOff = {((x + boutonCC[y]), 0)};
ist vollkommen unklar.
Was soll das werden?
Was ist boutonCC[y]?

Viel zu viele Fragen und viel zu undurchsichtig.
Erzähl mal was das werden soll.

Hallo , es soll mal die Registersteuerung einer virtuellen (Pfeifen )Orgel werden . Dafuer sind bei mir drei CD4021 zum Einlesen der 24 Taster und drei 595 fuer die Ausgabe des Zustandes der Taster an die jeweils 24 LED-s .Die Schaltung soll einen MIDI Befehl mit EIn/Aus ,Tasternummer ausgeben bei Veraenderung des Schaltzustandes jedwelchen Tasters . Den Ursprungs-Code habe ich weiter oben angefuegt und zugleich auch den Link zu dem Projekt( die Seite zu der verlinkt wird ist leider nicht mehr erreichbar) . Und wegen des "codes" bitte nicht steinigen ich bin gaanz am Anfang mit Arduino. Vielen Dank !

Na das ist ja spannend...
Was mich verwirrt, ist die Abfrage der Tasten:

Was ist denn flag?
Die ganze Funktion kommt nirgendwo zum Einsatz.
Was ist boutonCC[]

Ich bin ja fast geneigt, das komplett neu aufzusetzen und wachsen zu lassen. Das mit dem Code wird eher eine Operation und dafür braucht es sehr viel Zeit und Geduld.
Und ich selbst (und vermutlich auch ein großer Teil der Leser hier) verfügt nicht über die Hardware. Das wird also ein Blindflug.
Auch den mach ich schon immer, aber das wird raten auf hohem Niveau....

Na mal sehen, was ich da raus bekomme.

Ich weiss es nicht was diese Funktion ist, sie ist im urspruenglichen code dort vorhanden , ich habe die Schaltung aufgebaut so wie oben beschrieben , das mit den Tastern und Led-s funktioniert auch so wie es soll, beim druecken des ersten Tasters -1. Led an , nochmal druecken 1.Led aus , das bei allen 24 .Was mir dabei fehlt ist die Ausgabe ueber MIDIUSB derZustaende der Taster . Danke !

Da mein Französisch vor mindestens 60 Jahren irgendwo liegen geblieben ist: Ich bau Dir das gerne so, dass Du die Tasten abgefragt bekommst und das auch auf die MIDI-Schnittstelle bekommst, aber nicht mit dem Code.
Da weder Du noch ich den Code verstehen.

Deine Entscheidung.

das waere suuper , mich interessiert es nicht dass es dieser franz. code sein muss


Das ist meine Platine , in der Mitte die Ausgaenge zu den Led-s , unten Taster Eingaenge und seitlich zum Arduino Leonardo .

1 Like

Au schick! :star_struck:
Bekomme ich den Plan da drunter als PDF Oder JPG?
Das ist ja fast selbsterklärend....

DigitalBoard v1.3.pdf (28.1 KB)
das ist der originale Schaltplan, ein wenig verworren ist die Anbindung zum Arduino ,
Midiboard v1.4.pdf (34.5 KB)
das habe ich auch gebaut , dazu brauche ich noch einen MIDI -USB Konverter , daher waere die Loesung mit Arduino Leonardo und Ausgabe per USB direkt aus dem Arduino viel besser fuer mich . Ich habe das IC 4520 auf dem MIDI-Board nicht eingesetzt da es nur dazu dient auch Analoge Signale von einer anderen Platine abzufragen
AnalogBoard v1.2.pdf (14.9 KB)
dieser Aspekt interessiert mich nicht .

1 Like

Wenn ich das jetzt richtig verstanden habe, hast Du 3 Stück 4021 in Serie, sodass Du 24 Tasten hast, die Du mit einem PIN abfragst.
Und dazu auch passend 3 Stück 595.

Die passende LED am 595 soll bei ausgelöstem Pin an den 4021 leuchten.

Und passend dazu soll das Midi-Commando zu jedem State-Wechsel ausgelöst werden.

Dabei gilt:
Note an wird eingeleitet mit 0x09, 0x90,gefolgt von der Note und 0x0F
Note aus wird eingeleitet mit 0x08, 0x80, gefolgt von der Note und 0x00

Jetzt brauch ich nur noch den Wert für die 24 Noten.

ja , ich habe je 3 stueck Schieberegister auf jeder Seite verbaut ,die Taster schalten beim Antippen die Led ein ( bleibt dann auf ein ) bis zum zweiten mal antippen -dann geht sie aus . Die originale Version gibt die Befehle auf die Noten von 20 bis 43 aus .

1 Like

Dann bekommst Du das auch auf die 20 bis 43.

Es macht Spass mit Dir.
Danke!

ich bin zu Dank verpflichtet !

Ohne Anspruch, dass das funktioniert.
Bin noch am basteln...

#include "MIDIUSB.h"

constexpr uint8_t shiftRegs {3};                      // Anzahl ShiftRegister - IN und OUT sollen die gleiche Anzahl haben!
constexpr uint8_t pinsOnRegs {8};                     // Anzahl Pins am Register - Für beide gleich!

constexpr bool isPressed {LOW};                       // Vorbelegung Taste aktiv

constexpr bool ledOn {HIGH};
constexpr bool ledOff {!ledOn};

constexpr uint32_t debounceTime {50};                 // Entprellzeit in ms / Abfrageintervall

constexpr uint8_t midiChannel {0};
constexpr uint8_t anschlag {127};                     // MidiNote

struct CHIPIN                                         // Input Chip 4021 - was zusammengehört
{
  bool pinState[pinsOnRegs];                          // Zustand der Taste - HIGH/LOW
  bool lastPinState[pinsOnRegs];                      // Letzter Zustand der Taste
};

constexpr uint8_t shiftClockPin {2};                  // erklärt sich selbst

struct IN                                             // Input Kaskade
{
  static constexpr uint8_t latchPin {3};
  static constexpr uint8_t dataPin {4};
  uint32_t pinTime;                                   // Zeitpunkt letzte Abfrage

  CHIPIN ch[shiftRegs] =
  {
    {{0, 0, 0, 0, 0, 0, 0, 0, }, {0, 0, 0, 0, 0, 0, 0, 0, },},       // {pinStatus}, {lastPinStatus},
    {{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, },},
  };
} in;

struct CHIPOUT                                        // Output Kanal - was zusammengehört (und für die gleiche Darstellung im Code)
{
  bool outPinState[pinsOnRegs];                       // 8 PIN je Chip - jeweils 1 LED
  // HINWEIS: Ich habe mich gegen das durchzählen entschieden Es kann für jede Taste die Note festgelegt werden!
  const uint8_t note[pinsOnRegs];                     // Note die ausgegeben wird
};

struct OUT
{
  static constexpr uint8_t latchPin {5};
  static constexpr uint8_t dataPin {6};
  CHIPOUT ch[shiftRegs] =    // Wie IN
  {
    {{0, 0, 0, 0, 0, 0, 0, 0,}, {20, 21, 22, 23, 24, 25, 26, 27,},}, // {LED-Status}, {Note}
    {{0, 0, 0, 0, 0, 0, 0, 0,}, {28, 29, 30, 31, 32, 33, 34, 35,},},
    {{0, 0, 0, 0, 0, 0, 0, 0,}, {36, 37, 38, 39, 40, 41, 42, 43,},},
  };
} out;

void setup()
{
  Serial.begin(115200);
  MidiUSB.flush(); // Initialize the MIDIUSB library
  pinMode(shiftClockPin, OUTPUT);
  digitalWrite(shiftClockPin, HIGH);
  initShiftIn();
  initShiftOut();
}

void loop()
{
  if (millis() - in.pinTime > debounceTime)
  {
    getShiftInData();
    setShiftOutData();
  }

  // Mididaten wiederholen?
}

void initShiftIn()                                         // Initialisation und Vorbelegung
{
  pinMode(in.latchPin, OUTPUT);
  digitalWrite(in.latchPin, LOW);
  pinMode(in.dataPin, INPUT);
  getShiftInData();
}

void initShiftOut()
{
  pinMode(out.latchPin, OUTPUT);
  digitalWrite(out.latchPin, LOW);
  pinMode(out.dataPin, OUTPUT);
  digitalWrite(out.dataPin, LOW);
  setShiftOutData();
}

void shiftReadStart()                                      // Startsequenz zum lesen
{
  digitalWrite(shiftClockPin, HIGH);                     // Vorbereitung zum Takten
  digitalWrite(in.latchPin, HIGH);                       // Vorbereiten zum auslesen
  delayMicroseconds(20);
  digitalWrite(in.latchPin, LOW);
}

void shiftTakt()
{
  digitalWrite(shiftClockPin, LOW);                  // Takt zum schieben
  delayMicroseconds(2);
  digitalWrite(shiftClockPin, HIGH);
}

void getShiftInData()                                 // Liest alle Register ein
{
  shiftReadStart();

  for (uint8_t chip = 0; chip < shiftRegs; chip++)    // Zähle durch die Chips
    for (uint8_t pin = 0; pin < pinsOnRegs; pin++)    // Zähle die Pins je Chip
    {
      in.ch[chip].pinState[pin] = digitalRead(in.dataPin); // Status übernehmen
      shiftTakt();
    }

  in.pinTime = millis();                              // Auslesezeit merken
}                                                     // Alle Pins ausgelesen

void setLedState()
{
  digitalWrite(shiftClockPin, LOW);
  digitalWrite(out.dataPin, LOW);
  digitalWrite(shiftClockPin, LOW);

  for (uint8_t chip = 0; chip < shiftRegs; chip++)                         // Zähle durch die Chips
  {
    for (uint8_t pin = 0; pin < pinsOnRegs; pin++)                         // Zähle die Pins je Chip
    {
      digitalWrite(shiftClockPin, LOW);
      digitalWrite(out.dataPin, out.ch[chip].outPinState[pin]);
      digitalWrite(shiftClockPin, HIGH);
      digitalWrite(out.dataPin, LOW);
    }

    digitalWrite(shiftClockPin, LOW);
    digitalWrite(out.latchPin, HIGH);
  }
}

void setShiftOutData()
{
  bool isNew = false;

  for (uint8_t chip = 0; chip < shiftRegs; chip++)                         // Zähle durch die Chips
  {
    for (uint8_t pin = 0; pin < pinsOnRegs; pin++)                         // Zähle die Pins je Chip
    {
      if (in.ch[chip].pinState[pin] != in.ch[chip].lastPinState[pin])      // Das BIT hat sich geändert?
      {
        if (in.ch[chip].pinState[pin] == isPressed)                        // Taste gedrückt?
        {
          out.ch[chip].outPinState[pin] = !out.ch[chip].outPinState[pin];

          if (out.ch[chip].outPinState[pin] == ledOn)                      // Ist nicht gesetzt ?
          { noteOn(midiChannel, out.ch[chip].note[pin], anschlag); }       // Note senden
          else                                                             // War gesetzt ?
          { noteOff(midiChannel, out.ch[chip].note[pin], 0); }             // Note löschen

          isNew = true;
        }

        in.ch[chip].lastPinState[pin] = in.ch[chip].pinState[pin];         // Status merken
      }
    }
  }

  if (isNew)
  { setLedState(); }
}

void controlChange(byte channel, byte control, byte value)
{
  byte chan = 0xB0 | channel;
  midiEventPacket_t event = {0x0B, chan, control, value};
  MidiUSB.sendMIDI(event);
}

void noteOn(byte channel, byte pitch, byte velocity)
{
  byte chan = 0x90 | channel;
  midiEventPacket_t noteOn = {0x09, chan, pitch, velocity};
  MidiUSB.sendMIDI(noteOn);
}

void noteOff(byte channel, byte pitch, byte velocity)
{
  byte chan = 0x80 | channel;
  midiEventPacket_t noteOff = {0x08, chan, pitch, velocity};
  MidiUSB.sendMIDI(noteOff);
}

Hallo ,vielen Dank zuerst, habe den code auf den Arduino geladen , so wie ich gesehen habe sind die Anschlusspins die gleichen geblieben .Was ich bemerkt habe ist dass wenn ich Taster 1 am ersten 4021 druecke die entsprechende Led angeht ,aber nicht mehr aus , auch wenn ich Taster 1 nochmal betaetige , scheinbar auch bei Taster 2 so, bei den anderen habe ich es noch nicht versucht da ich mir noch eine Leiste mit 8 LED-s zusammenloeten muss um alle 8 Ausgaenge pro IC zu pruefen . Es werden auch MIDI Befehle ausgegeben aber nicht sofort wenn der Taster gedrueckt wird sondern wenn ich mehrere taster betaetige dann kommt auf einmal ein ganzer Block von Befehlen , kann das mit dem Verhalten der LED-s zusammenhaengen ? Koennen in diesem code auch mehrere Taster (auch alle ) EIN sein oder nur immer einer ?

1 Like

Kümmer ich mich später drum.
Ich bin blos noch etwas unterwegs und auf die Schnelle war das so ein Ansatz.

Ja, die Idee war, dass ich das so übernehme, wie Du es schon zur Verfügung gestellt hast.
Ich hatte mit mir gehadert, den ClockPin für beide Shift-Kaskaden zu nehmen, aber anscheinend funktioniert das :wink:

Und ja, die Idee ist, dass Du zu jeder Taste einen Zustand bekommst und diese auch unabhängig voneinander sind.
Wenn Du also am ersten 4021 Taste 3, Taste 5 und am zweiten Taste 4 1x auslöst, dann sollen da auch genau so die entsprechenden LED's auslösen und passend der MIDI-Code geschickt werden.

Darum hatte ich ja gesagt, dass ich das lieber neu aufsetze, damit ich die ganze Geschichte modular bauen kann...

Code mache ich später.

Mach mal in die beiden Funktionen void noteOn und void noteOff als letzte Zeile jeweils ein: MidiUSB.flush(); rein.
Dann sollte das senden sofort gehen.
Mit den Tasten denke ich, habe ich nur auf der falschen Klammerebene die Rückstellung des Merkers. Muss ich aber auf später verschieben. Ich seh das nicht auf dem kleinen Netbook...