Schwierigkeit, nicht zu wissen wo anfangen mit MIDI-Schnittstelle



  • Hallo Community,

    ich bräuchte etwas welches die Midi-Daten von einem Tonprogramm (FL Studio) empfängt und sie weiterverarbeitet zu einer USB-Schnittstelle an Arduino.

    Deswegen die grundlegenden Fragen:

    - Welche MIDI-Library funktioniert und ist einfach zu benützen?
    Ich hätte gerne so etwas wie ein Example, damit ich schnell einsteigen kann mit meiner Ungeduld.
    - Mir fehlen noch die Erfahrungen mit USB-Daten. Arduino ist ein Mikroprozessor mit USB-Anschluss. Schließe ich sie am PC, wird sie immer als COM mit einer Nummer dahinter (z.B. COM1) erkannt.

    Als API versuche ich mal mit Qt, da ich Erfahrungen von früher damit habe.
    Ein Programm mit zwei Dropmenüs, welche Midi-Input auszuwählen ist und an welchem COM.

    Wenn so ein Code für Arduino vielleicht schon gibt dann lieber das. Es geht darum mit MIDI ganz viele Servomotoren anzusteuern. Wichtig: Es muss über USB sein.



  • MIDI ist schon simpel. Glaube nicht, dass es dafür eine Bibliothek gibt. Höchstens für SysEx und Midifiles, aber das willst Du wohl nicht.

    Mfg Martin





  • theta schrieb:

    http://playground.arduino.cc/Main/MIDILibrary
    https://github.com/ddiakopoulos/hiduino
    ???

    midi kabel direkt an arduino habe ich schon versucht. Funktioniert zwar, ist aber sehr langsam. Ruckelt alles, vermutlich weil arduino zu langsam ist. Will eine Software aufm PC schreiben.

    Wenn es so simple ist, wie empfange ich im C++ dann die Mididaten die ein Musikprogramm aussendet?



  • xBlackKnightx schrieb:

    theta schrieb:

    http://playground.arduino.cc/Main/MIDILibrary
    https://github.com/ddiakopoulos/hiduino
    ???

    midi kabel direkt an arduino habe ich schon versucht. Funktioniert zwar, ist aber sehr langsam. Ruckelt alles, vermutlich weil arduino zu langsam ist. Will eine Software aufm PC schreiben.

    Wenn es so simple ist, wie empfange ich im C++ dann die Mididaten die ein Musikprogramm aussendet?

    MIDI überträgt gerade mal 4k/s. Das sollte der Arduino doch schaffen.

    In C++ öffnest Du einfach die Datei unter /dev Deines Midiports. Alles, was über MIDI-in reinkommt, kannst Du einfach lesen. Alles, was Du schreibst, geht zum MIDI-out.

    Was weißt Du denn über MIDI?

    Mfg Martin



  • mgaeckler schrieb:

    xBlackKnightx schrieb:

    theta schrieb:

    http://playground.arduino.cc/Main/MIDILibrary
    https://github.com/ddiakopoulos/hiduino
    ???

    midi kabel direkt an arduino habe ich schon versucht. Funktioniert zwar, ist aber sehr langsam. Ruckelt alles, vermutlich weil arduino zu langsam ist. Will eine Software aufm PC schreiben.

    Wenn es so simple ist, wie empfange ich im C++ dann die Mididaten die ein Musikprogramm aussendet?

    MIDI überträgt gerade mal 4k/s. Das sollte der Arduino doch schaffen.

    In C++ öffnest Du einfach die Datei unter /dev Deines Midiports. Alles, was über MIDI-in reinkommt, kannst Du einfach lesen. Alles, was Du schreibst, geht zum MIDI-out.

    Was weißt Du denn über MIDI?

    Mfg Martin

    Ich hab gesehen dass das eine neuere Version von Midi Library war mit einigen bugfixes. Hatte vorhin die dreier Version. Vorhin hatte ich nur Serial.avaible Funktion von Arduino verwendet. Mit der Library geht es jetzt tatsächlich ruckelfrei.

    Danke für den Tip





  • USB ist Paketorientiert und damit nicht echtzeitfähig, wie Midi oder der serielle Anschluss.

    Das dürfte das größte Problem sein.

    Bei USB müßtest du im Prinzip mehrere Kommandos im Burst Modus an dein Arduino schicken, bei echtem Midi schickst du das Zeugs Befehl für Befehl raus, wann du es halt brauchst.



  • Sicher das USB problematischer wäre? Also ich habe jetzt die neuere Library von da benützt: http://playground.arduino.cc/Main/MIDILibrary und das ganze geht über Midi-Kabel.

    Die Probleme bestehen wie nach zu vor. Da sind 16 baugleiche Servos angeschlossen 4 Servos sollen im Gleichtakt bewegen und die anderen 4 Servos in anderem Gleichtakt bewegen. Die restlichen 8 Servos bleiben unbewegt.
    Das Musikprogramm "Fl Studio" schickt diese Controldaten in Midi an diese Servos. Trotzdem bekommen die Servos Störungen. Gemessen am Oszilloskop konnte ich sehen dass die Störung schon im Pulsweitenmodulation liegt. Die Servos sind also Ok.
    Die Servos die sich nicht bewegen sollten, bewegen sich manchmal unwillkürlich mit. Und die bewegenden Servos bekommen auch Störungen.

    Passen überhaupt soviele Midi-Signalen in diese 4k/s ? Es sind nicht diese Noten die abgespielt werden (die verbrauchen natürlich sehr wenig Daten), sondern Controldaten (das was am Mischpult gedreht oder geschoben wird.) Da werden viel mehr Informationen gespeichert und geschickt. So als würde ich am Mischpult 16 Potentiometer auf einmal drehen.

    Hab ein extra Screenshot gemacht:
    http://fs2.directupload.net/images/150305/nrrh44u9.jpg
    Oben Noten, unten Controldaten.

    Die Controldaten die ihr seht, davon 16 mal gleichzeitig in unterschiedlichsten Kurven.

    Und der Code für Arduino

    // Includes&Defines SERVO
    
    #include <Wire.h>
    #include <Adafruit_PWMServoDriver.h>
    Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
    
    #define SERVOMIN  100 // this is the 'minimum' pulse length count (out of 4096)
    #define SERVOMAX  600 // this is the 'maximum' pulse length count (out of 4096)
    
    #define SERVOMIN9G 175
    #define SERVOMAX9G 640
    
    // Includes&Defines MIDI
    
    #include <MIDI.h>
    
    #if defined(ARDUINO_SAM_DUE) || defined(USBCON)
        // Print through USB and bench with Hardware serial
        MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI);
    #else
        #include <SoftwareSerial.h>
        SoftwareSerial midiSerial(2,3);
        MIDI_CREATE_INSTANCE(SoftwareSerial, midiSerial, MIDI);
    #endif
    
    // -----------------------------------------------------------------------------
    
    uint8_t pos[7];
    
    void handleControlChange(byte channel, byte number, byte value)
    {
    
          if ((number >= 1) && (number <= 16)) 
             pwm.setPWM(number-1, 0, map(value, 0, 127, SERVOMIN9G, SERVOMAX9G));
    }
    
    // -----------------------------------------------------------------------------
    
    void setup()
    {
    
        MIDI.setHandleControlChange(handleControlChange);
    
        // Initiate MIDI communications, listen to all channels
        MIDI.begin(MIDI_CHANNEL_OMNI);
    
        while(!Serial);
        Serial.begin(115200);
        Serial.println("Arduino Ready");
    
        // start setup adafruit
        pwm.begin();
        pwm.setPWMFreq(60); 
        // end setup adafruit  
    
    }
    
    void loop()
    {
        // Call MIDI.read the fastest you can for real-time performance.
        MIDI.read();
    
        // There is no need to check if there are messages incoming
        // if they are bound to a Callback function.
        // The attached method will be called automatically
        // when the corresponding message has been received.
    }
    


  • Du meinst, mit Deiner Information kann irgendjemand was anfangen.

    Wenn ich Deinen Code richtig interpretiere, erhalten Deine Servos gar keine MIDI-Daten sondern werden über die Klasse Adafruit_PWMServoDriver gesteuert.

    Du hast also nur Deine Software via MIDI angesteuert. So weit ich das sehe, wird an Hand der MIDI-ControllerNumber Dein Servo ausgewählt. Der MIDI-Channel ist irrelevant. Möglicherweise kannst Du Deine MIDI-Quelle so konfigurieren, daß ControlChanges immer nur für 1 MIDI-Kanal gesendet werden.

    BTW: Control Messages sind nicht größer wie Noten-Messages (beides jeweils 3 Byte).

    Du mußt auf jeden Fall überprüfen, ob Du die MIDI-Befehle bekommst, die Du erwartest. Auf der anderen Seite solltest Du kontrollieren, ob Deibne Servo steuerung das macht, was Du erwartest.

    mfg Martin



  • Vielen Dank für die Antwort. Es liegt an den Midi-Befehle die nicht immer wie erwartet ankommen. Das kann ich nachsehen in Serial out. Ich spiele immer wieder den selben song ab, und was in serial out angezeigt wird, kommen manchmal andere Befehle raus.

    Hier ein Beispiel (erstes beispiel ist sauber und ok):

    channel - number - value

    [ 1 - 9 - 16 ] 
     [ 1 - 8 - 36 ] 
     [ 1 - 7 - 47 ] 
     [ 1 - 6 - 63 ] 
     [ 1 - 5 - 38 ] 
     [ 1 - 4 - 50 ] 
     [ 1 - 3 - 73 ] 
     [ 1 - 2 - 55 ] 
     [ 1 - 1 - 42 ] 
     [ 1 - 9 - 16 ] 
     [ 1 - 5 - 22 ] 
     [ 1 - 7 - 22 ] 
     [ 1 - 1 - 22 ] 
     [ 1 - 3 - 22 ] 
     [ 1 - 6 - 33 ] 
     [ 1 - 5 - 31 ] 
     [ 1 - 4 - 33 ] 
     [ 1 - 8 - 33 ] 
     [ 1 - 2 - 33 ] 
     [ 1 - 7 - 31 ] 
     [ 1 - 1 - 31 ] 
     [ 1 - 3 - 31 ] 
     [ 1 - 6 - 35 ] 
     [ 1 - 4 - 35 ]
    

    dann kommt es so mit fehler:

    [ 1 - 9 - 16 ] 
     [ 1 - 8 - 36 ] 
     [ 1 - 7 - 47 ] 
     [ 1 - 6 - 63 ] 
     [ 1 - 5 - 38 ] 
     [ 1 - 4 - 50 ] 
     [ 1 - 3 - 73 ] 
     [ 1 - 2 - 55 ] 
     [ 1 - 1 - 42 ] 
     [ 1 - 9 - 16 ] 
     [ 1 - 5 - 22 ] 
     [ 1 - 7 - 22 ] 
     [ 1 - 1 - 22 ] 
     [ 1 - 3 - 22 ] 
     [ 1 - 25 - 133 ] 
     [ 1 - 6 - 38 ] 
     [ 1 - 6 - 41 ] 
     [ 1 - 176 - 6 ] 
     [ 1 - 25 - 98 ] 
     [ 1 - 5 - 32 ] 
     [ 1 - 7 - 32 ] 
     [ 1 - 6 - 176 ] 
     [ 1 - 6 - 48 ] 
     [ 1 - 51 - 154 ]
    

    beim dritten replay kommt diese reihenfolge:

    [ 1 - 9 - 16 ] 
     [ 1 - 8 - 36 ] 
     [ 1 - 7 - 47 ] 
     [ 1 - 6 - 63 ] 
     [ 1 - 5 - 38 ] 
     [ 1 - 4 - 50 ] 
     [ 1 - 3 - 73 ] 
     [ 1 - 2 - 55 ] 
     [ 1 - 1 - 42 ] 
     [ 1 - 9 - 16 ] 
     [ 1 - 5 - 22 ] 
     [ 1 - 7 - 22 ] 
     [ 1 - 1 - 22 ] 
     [ 1 - 3 - 22 ] 
     [ 1 - 6 - 33 ] 
     [ 1 - 62 - 193 ] 
     [ 1 - 1 - 10 ] 
     [ 1 - 6 - 67 ] 
     [ 1 - 10 - 14 ] 
     [ 1 - 77 - 40 ] 
     [ 1 - 50 - 182 ] 
     [ 1 - 6 - 35 ] 
     [ 1 - 4 - 35 ] 
     [ 1 - 8 - 35 ]
    

    Zeilen wie diese hier dürften gar nicht vorhanden sein:

    [ 1 - 176 - 6 ] 
     [ 1 - 25 - 98 ]
    

    Woher kommen sie? Ich habe herausgefunden dass diese Fehler seltener bis gar nicht vorkommen wenn ich diesen Midi-Song viel langsamer abspiele, also doppelt so langsam. Je schneller ich das abspiele, desto häufiger kommen diese unbekannten Befehle.
    Ich habe schon mit anderem Midi-Adapter versucht. Ohne Erfolg.



  • Wo hast Du das geprüft? Bei handleControlChange()? Oder schon am Ausgang Deines Musikcomputers? Oder am Ausgang Deines Arduinos?

    mfg Martin



  • mgaeckler schrieb:

    Wo hast Du das geprüft? Bei handleControlChange()? Oder schon am Ausgang Deines Musikcomputers? Oder am Ausgang Deines Arduinos?

    mfg Martin

    Im Ausgang meines Arduinos. Also der ist mit USB am PC angeschlossen. So habe ich Serial Out und kann am PC in der Console ablesen was sich im Arduino tut.

    handleControlChange() wird im Arduino ausgeführt.

    Deswegen stellt sich für mich immer noch die Frage ob's an der Software liegt, oder an der Hardware, oder an dem midi-Adapter, oder Arduino liest die Daten falsch ein.



  • xBlackKnightx schrieb:

    mgaeckler schrieb:

    Wo hast Du das geprüft? Bei handleControlChange()? Oder schon am Ausgang Deines Musikcomputers? Oder am Ausgang Deines Arduinos?

    mfg Martin

    Im Ausgang meines Arduinos. Also der ist mit USB am PC angeschlossen. So habe ich Serial Out und kann am PC in der Console ablesen was sich im Arduino tut.

    Also ganz am Ende Deiner Kette? Und Du schließt daraus, daß am Anfang etwas schief läuft? Aha.

    xBlackKnightx schrieb:

    handleControlChange() wird im Arduino ausgeführt.

    Kannst Du da nicht debuggen?

    xBlackKnightx schrieb:

    Deswegen stellt sich für mich immer noch die Frage ob's an der Software liegt, oder an der Hardware, oder an dem midi-Adapter, oder Arduino liest die Daten falsch ein.

    Erkäre doch bitte GENAU Dein Hardwaresetup. Dann über welche Verbindungen schickst Du welche Art von Daten?

    mfg Martin


Anmelden zum Antworten