i want to get some data transferred to the arduino via midi in as sysex-messages. i didn't solder my own midi in-interface but (ab)used a midi-to-usb-interface (something like this: shiftmore. blogspot. com/2010/01/quick-and-dirty-arduino-midi-over-usb.html).
since the serial port is blocked for midi in and out, i use a display for debugging.
this is the 76-byte-sysex-message (and midi monitor says it gets transmitted exactly like this):
I have the feeling that a delay(20); within the while-loop makes things better, but not much. When i send the sysex-message two times (very fast!), i get 22 bytes.
Do you guys have an idea what to do or at least in which direction to think? Is it something like a timeout-buffer-overflow-issue? i'm new to arduino and maybe missing some point...
Serial data is transmitted relatively slow. It can be read from the serial buffer faster than it can be received into the serial buffer. Since you stop reading as soon as the buffer is (temporarily) empty, you are not getting a whole packet before you stop reading.
If you know that a packet will contain n bytes, wait for n bytes to be available before reading, or don't process the accumulated data (not that you are accumulating it) until n bytes have been received.
Even better is to send some start of packet and end of packet markers. This enables you to deal with packets even when part of a packet is lost in shipping.
thank you for the fast response. unfortunately i didn't succed.
my new loop:
void loop() {
if (Serial.available() > 0 && Serial.read() == 0xF0)
{
delay(100);
byte incomingByte = Serial.read(); // Manufacturer ID = 0x7D = Educational
delay(100);
byte nr = Serial.read(); // This * 36 is the size of what comes
int count = 0;
int errorcount = 0;
for (int i = 0; i < (int)nr*36; ++i)
{
delay(300); // wait for data
incomingByte = Serial.read(); // read data byte
SysEx[i] = incomingByte; // store in byte array
if ((int)incomingByte == 255) errorcount++; // 255 == Error
count++;
}
lcd.setCursor(0,0);
lcd.print(count);
lcd.print(" Bytes"); // Output: 72 Bytes
lcd.setCursor(0,1);
lcd.print(errorcount);
lcd.print(" Errors"); // Output: 63 Errors
}
After 9 bytes i only get 255. When i print every read value as int, i get "valid" but not correct data. Instead of 53, 52, 54, 53, 55, 51... i get 48, 50, 48, 48...
waitForSerial is a good idea, thanks for that.
I never get out of the while-loop. It reads 9 bytes and then stops. when i send the same message again, it reads the next 9 bytes and idles again. when i change the sysex i send to something else, it reads again only the first few bytes of it (i tried "F0 00 20 3C 01 00 03 F7", taken from http://www.teknopipo.nl/archives/677 and got 1, then 3, then 2 bytes from each transmission).
may it be that the usb-midi-interface i use drops the sysex once it checked the manufacturer id or some other data and came to the conclusion that its not meant for it? since a midi-to-usb is little more than an adapter it should forward everything, but what comes out of the computer seems right, how incoming data on the arduino is handled seems right, only thing in between is this interface.
What software(?) are you using to send the SysEx messages?
Your USB adapter shouldn't be changing the messages... and I doubt that the one you posted would be different. Have you tried it with any kind of midi hardware (other than the Arduino) e.g. keyboards etc.?
i use a homebrew java program. i didn't try it with any other hardware, because the sysex wouldn't be understood by any other midi device except the one i program for it. but i sent it to midi monitor, looked at the data and it was correct. midi monitor also confirms every transmission of the sysex to the arduino.
maybe to clarify: i want to use the arduino as a midi controller. its display should show some data (title of a song) and this (and little more) data has to be transferred to the arduino. the only way to transfer data "freely" via midi is sysex.
The only other thing I can think to check at this point is that you're definitely sending F0 and F7 etc. as numbers (i.e. 240 and 247) and not character strings (i.e. 70 48 (Ascii F0))
Failing that, I don't know mate. I'm tempted to build the circuit myself to work on it, but it'd probably be the weekend before I got the time to try that.
this works right away. sysex is treated as an orphan in many interfaces, devices and libraries, so i stay with more standard midi messages. it's not what i wanted but it works.
one last thing (for all you who google for midi in arduino sysex):
easy on the serial line! even with my CC-messages i had problems to get consistent messages. i have a delay of 100ms between every CC-command i send. even with the waitforserial-thing i only get like 5 or 6 bytes without it.