SysEx send and receive over USB

Dear,

Can I send and receive SysEx messages over USB (USBMIDI library or similar)?

Note On and Off and CtrlChange it is easy to implement...

Thanks
MJ

Why would it not be possible? MIDI is just a serial stream

I am new in arduino... :slight_smile:

The field of my expertise is Acoustics and I deal with Matlab... Comsol...

If you look at the various resources out there about MIDI messages you'll see they are all just
bytes sent down a wire, if you can send one kind of message, you can send any message. If
you are receiving MIDI you should be able to deal with (if only to ignore) any kind of message too,
unless you know it won't be used.

Yes, thanks MarkT!

But how to realize that!?

Software like ProTools, Cubase...deal with two type of MIDI messeages...
The firste one are 3 bytes length messages like NoteOn, NoteOff, ControlChange... and second are variable length SysEx messages (e.g. in HUI Protocol format).

This is messages readed in MidiOx from Cubase:

F0,00, 00, 66, 05, 00 10, 00, 6D, 61, 72, 65, F7

0xF0, 0x00, 0x00, 0x66, 0x05, 0x00 - this is header of any Sysex in HUI protocol

0x10, 0x00, 0x6D, 0x61, 0x72, 0x65 - this is "data"

0xF7 - and this is END of SysEx in HUI protocol

0xF0 - this is START SysEx (from header).

In this messages we have 13 bytes.

I try to modify MIDIUSB.h and MIDIUSB_Write.ino example in the folowing way:

In MIDIUSB.h (library) now in example.ino named MIDIUSB_05.h:

#if !defined(USBCON)
#error MIDIUSB can only be used with an USB MCU.
#endif

typedef struct
{
uint8_t header;
uint8_t byte1;
uint8_t byte2;
uint8_t byte3;
uint8_t byte4;
uint8_t byte5;
uint8_t byte6;
uint8_t byte7;
uint8_t byte8;
uint8_t byte9;
uint8_t byte10;
uint8_t byte11;
uint8_t byte12;
uint8_t byte13;

}midiEventPacket_t;

and in MIDIUSB_Write.ino:

#include "MIDIUSB_05.h"

void SysEx(byte one, byte two, byte tree, byte four, byte five, byte six, byte seven, byte eight, byte nine, byte ten, byte eleven, byte twelve, byte thirteen) {
midiEventPacket_t SysEx = {one, two, tree, four, five, six, seven, eight, nine, ten, eleven, twelve, thirteen};
MidiUSB.sendMIDI(SysEx);
}

void setup() {
Serial.begin(31250); // Standard MIDI baud rate
}

void loop() {
SysEx(0xF0, 0x00, 0x00, 0x66, 0x05, 0x00, 0x10, 0x00, 0x6D, 0x61, 0x72, 0x65, 0xF7);
MidiUSB.flush();
delay(1000);
}

Arduino done uploading and send data (tx led blinking at evry 1000ms) but software like MidiOX and other (Cubase, ProTools) can detect SysEx messages!
Where is the problem?

Where is the problem?

The problem is that you have not read the rules How to use this forum

Not only will it tell you how to post code so that others can easily try your code, it also tells you to post links to obscure libraries. The #include "MIDIUSB_05.h" is not part of the standard MIDIUSB libiary, so I can't get what you wrote to compile.

These rules have been honed over the years so that we don't have to waste time, EVERY TIME, someone wants help but fails to supplies enough information.

The problem is that USB MIDI messages can only have four bytes, so you have to drip feed the data to it :-
The send function from Sending arbitrary length MIDI messages · Issue #19 · arduino-libraries/MIDIUSB · GitHub I wrote the code round it.

#include "MIDIUSB.h"

byte message[] = {0xF0,0x00, 0x00, 0x66, 0x05, 0x00, 0x10, 0x00, 0x6D, 0x61, 0x72, 0x65, 0xF7};

void setup() {
  while(!Serial) {};
}

void loop() {
  MidiUSB_sendSysEx(message,sizeof(message));
  MidiUSB.flush(); 
  delay(1000);
}

void MidiUSB_sendSysEx(const uint8_t *data, size_t size)
{
    if (data == NULL || size == 0) return;

    size_t midiDataSize = (size+2)/3*4;
    uint8_t midiData[midiDataSize];
    const uint8_t *d = data;
    uint8_t *p = midiData;
    size_t bytesRemaining = size;

    while (bytesRemaining > 0) {
        switch (bytesRemaining) {
        case 1:
            *p++ = 5;   // SysEx ends with following single byte
            *p++ = *d;
            *p++ = 0;
            *p = 0;
            bytesRemaining = 0;
            break;
        case 2:
            *p++ = 6;   // SysEx ends with following two bytes
            *p++ = *d++;
            *p++ = *d;
            *p = 0;
            bytesRemaining = 0;
            break;
        case 3:
            *p++ = 7;   // SysEx ends with following three bytes
            *p++ = *d++;
            *p++ = *d++;
            *p = *d;
            bytesRemaining = 0;
            break;
        default:
            *p++ = 4;   // SysEx starts or continues
            *p++ = *d++;
            *p++ = *d++;
            *p++ = *d++;
            bytesRemaining -= 3;
            break;
        }
    }
    MidiUSB.write(midiData, midiDataSize);
}

This is the result on my MIDI Monitor screen

:slight_smile: thanks!!! I try!