Midi Note On Message empfangen

Hallo zusammen,

ich hab mein Keyboard mit dem Arduino per MIDI verbunden. Die MIDI IN Schaltung habe ich wie bei notesandvolts gezeigt, aufgebaut.

Wenn ich eine Taste bei meinem Key drücke wird eine Note On Message (144) an den Arduino gesendet. Doch leider erkennt der Arduino nicht immer gleich, dass eine Note On Message eingegangen ist.
Falls er eine Note On Message erkennt, muss ich ca. 10 sec warten, sodass der Arduino gleich die nächste Note On Message beim erstmaligen drücken einer Keyboard Taste, erkennt.

Kurz um; der Arduino ist zu langsam für die Auswertung. Wo mache ich den Fehler?

byte commandByte;

void setup(){

  Serial.begin(31250);
  }

void loop(){
  
  commandByte = Serial.read(); 


  if (noteByte == 144) //Note On wird empfangen
  {
    Serial.write(144);    //Note ON 
    Serial.write(13);      //Note 13
    Serial.write(100);    //Velocity 100
  }
  
}

Schöne Grüße
Andy

Das Programm ist unvollständig / compiliert nicht.

Serial.read() wird ohne vorheriges Serial.available() aufgerufen.

commandByte wird gelesen, noteByte verglichen.

Whandall:
Serial.read() wird ohne vorheriges Serial.available() aufgerufen.

Bei dieser Variante ist das kein Problem solange man nicht auf 255 abfragt

Serial.read() gibt -1 zurück wenn nichts zu lesen ist. Wenn man also in einen int einliest, passen alle Vergleiche danach.

Dann gibt es in dem Programm überhaupt kein Problem, es compiliert ja nicht. :wink:

Und dass commandByte ein int ist, erscheint mir eher unwahrscheinlich, zumindestens nicht beabsichtigt.

Ja, mit den Variablen stimmt was nicht. Aber am fehlenden available() scheitert es nicht :slight_smile:

Es ist nicht falsch read() ohne available() zu benutzen,

aber langsamer, unhandlicher, sinnentstellend* (0xFF ist auf einmal ungültig), schwerer zu handhaben.

Ich würde davon abraten. Aber jeder wie er mag.

Edit: * bei der obigen Benutzung...

arduinoknight:
Wo mache ich den Fehler?

Den Fehler dürftest Du bei der Hardware machen.

Eine serielle Schnittstelle stellt immer eine Point-to-Point Verbindung zwischen ZWEI Teilnehmern her. Der TX-Sendepin des einen Teilnehmers ist mit dem RX-Empfangspin des anderen Teilnehmers verbunden.

Bei den meisten Arduino-Boards (z.B. UNO, MEGA) ist "Serial" bereits mit einem USB-Seriell Chip verbunden, der über das USB-Kabel eine Verbindung ZUM PC herstellt. Da sind also Pin-0/1 bereits reserviert für die serielle Verbindung zum USB-Seriell Treiberchip auf dem Arduino-Board und für eine serielle Verbindung des Boards zum PC.

Du kannst bei solchen Boards "Serial" nicht für eine serielle Verbindung zu einem anderen seriellen Gerät verwenden. Damit testest Du allenfalls, welcher Schnittstellentreiber stärker ist: Der vom USB-Seriell Chip auf dem Arduino-Board, oder der auf Deinem anderen Gerät. Also Kurzschluss gegen Kurzschluss - möge der stärkere mit seinen gesetzten Bits gewinnen!

Wenn Du keinen Treiberwettkampf durchführen möchtest, um die stärksten Ausgangstreiber zu ermitteln und aus welcher Schnittstelle als erstes Rauch herauskommst, darfst Du das so nicht zusammenschließen.

Also zeig mal zuerst Deine Schaltung vor, aus der hervorgeht welches Arduino-Board Du verwendest und was Du genau wo angeschlossen hast! Und wenn da dann rauskommt, dass z.B. das Arduino-Board ein UNO ist, dessen USB-Anschluss Du mit einem PC verbunden hast, aber bei dem Du auch Pin-0 und Pin-1 mit Deiner MIDI-Schnittstelle verbunden hast, dann hast Du einen Kurzschluss gebastelt.

Wenn Du MIDI-Daten von etwa einer MIDI-Schnittstelle empfangen und an den PC weiterleiten wolltest, würde das z.B. so aussehen:

void setup(){
  Serial.begin(31250); // initialisiere die Schnittstelle "Serial" zum PC
  Serial1.begin(31250); // initialisiere die Schnittstelle "Serial1" zum MIDI-Gerät
}

Wozu Du natürlich erstmal ein Arduino-Board mit zwei seriellen Schnittstellen haben müßtest. Oder Du müßtest die zweite serielle Schnittstelle in Software emulieren, wenn das Board keine zweite serielle Schnittstelle hat.

Sorry, hab den falschen Sketch hoch geladen.

byte commandByte;
//byte noteByte;
//byte velocityByte;

 void setup(){
  Serial.begin(31250);
  }

void loop(){
  
  commandByte = Serial.read(); //Note On
    //noteByte = Serial.read(); // Note 
    //velocityByte = Serial.read(); //Velocity

  if (commandByte == 144) //Note On Message empfangen
  {
    Serial.write(144);
    Serial.write(13);
    Serial.write(100);
  }
  
}

Dieser Sketch "funktioniert" eigentlich schon, nur werden halt nur manchmal Note On Message erkannt.
Irgendwas muss den Datentransport des Arduinos (Nano) , nach Empfang einer Note On Message (vom Keyboard), für kurze Zeit blockieren, sodass drauf folgende Note On Messages verloren bzw. nicht abgearbeitet werden.

@ jurs: Ich benutze dafür nicht die Serielle Übertragung per Usb, sondern die Hardware Lösung mit den beiden RX und TX Pins.

arduinoknight:
@ jurs: Ich benutze dafür nicht die Serielle Übertragung per Usb, sondern die Hardware Lösung mit den beiden RX und TX Pins.

Dann musst den Arduino aber nach dem Hochladen von USB trennen!

Oder emuliere dir eine serielle Schnittstelle in Software:
https://www.pjrc.com/teensy/td_libs_AltSoftSerial.html

Dann musst den Arduino aber nach dem Hochladen von USB trennen!

Leider hat das keine Besserung gebracht. :confused:

Ich habe aber stattdessen eine Midi Library (4.2) gefunden, die viel schneller auf Note On Messages reagiert.

In diesem Beispiel leuchtet die Led auf, wenn eine Note On Message eintrifft.

#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();

int ledPin = 13;

void handleNoteOn(byte channel, byte pitch, byte velocity)
{
    digitalWrite(ledPin, HIGH);
}

// -----------------------------------------------------------------------------
void setup()
{
  pinMode(ledPin, OUTPUT);
  
    MIDI.setHandleNoteOn(handleNoteOn);  
   
    MIDI.begin(MIDI_CHANNEL_OMNI);
}
void loop()
{
    
    MIDI.read();

}

Da ich im Anfangsstadium meiner Programmier Fähigkeiten bin, weis ich jetzt nicht wie ich bestimmte Noten von zb.
channal 1, pitch 60 , velocity 127 empfangen kann.

Wo muss ich die "Zahlen" im Sketch hinschreiben?

Vielen Dank für eure Hilfe!
Andy