lathoub / Arduino-USBMIDI

Allows a microcontroller, with native USB capabilities, to appear as a MIDI device over USB to a connected computer
MIT License
148 stars 11 forks source link

SysEx mode not work #6

Open YANG-Mingcong opened 3 years ago

YANG-Mingcong commented 3 years ago

Hello, first of all thank you very much for this great work!

When I tried your “example\SysEx” on the Arduino Due platform, I found that the package was not complete.

Image below is from MIDI Monitor on macOS

image

And I try to use USBPcap to capture the USB port data( file below can be open by wireShark)

test_20210121.pcap.zip image

seems only first 3 byte transport stable

lathoub commented 3 years ago

This issue will be resolved by #8

YuuichiAkagawa commented 3 years ago

@lathoub No. # 8 is a non-SysEx system message issue.

@YANG-Mingcong Me too. My Leonardo is works fine. but Due is not.

YuuichiAkagawa commented 3 years ago

I performed additional tests.

In Due, it seems that you have to wait after the flash.

https://github.com/lathoub/Arduino-USBMIDI/blob/866947ccd15dd408fce168f5e91029f4b1fc1007/src/USB-MIDI.h#L111-L112

I tried this and it worked.

                if (byte != MidiType::SystemExclusiveEnd){
                    SENDMIDI(mPacket);
                    delay(1);
                }

Reproduce code.

#include "MIDIUSB.h"

#define ENABLE_WAIT
#define WAITTIME 1
void sendSysEx(){
  midiEventPacket_t sysEx1 = {0x04, 0xF0, 0x43, 0x20};
  MidiUSB.sendMIDI(sysEx1);
  MidiUSB.flush();
#ifdef ENABLE_WAIT
  delay(WAITTIME);
#endif
  midiEventPacket_t sysEx2 = {0x04, 0x7E, 0x4C, 0x4D};
  MidiUSB.sendMIDI(sysEx2);
  MidiUSB.flush();
#ifdef ENABLE_WAIT
  delay(WAITTIME);
#endif
  midiEventPacket_t sysEx3 = {0x04, 0x20, 0x20, 0x38};
  MidiUSB.sendMIDI(sysEx3);
  MidiUSB.flush();
#ifdef ENABLE_WAIT
  delay(WAITTIME);
#endif
  midiEventPacket_t sysEx4 = {0x04, 0x39, 0x37, 0x33};
  MidiUSB.sendMIDI(sysEx4);
  MidiUSB.flush();
#ifdef ENABLE_WAIT
  delay(WAITTIME);
#endif
  midiEventPacket_t sysEx5 = {0x06, 0x50, 0xF7, 0x00};
  MidiUSB.sendMIDI(sysEx5);
  MidiUSB.flush();
}

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

void loop() {
  sendSysEx();
  delay(1000);
}
lathoub commented 3 years ago

Glad you found the issue. Based on your finding, it went to look on MIDIUSB (on which the library relies) and found a related issue: https://github.com/arduino-libraries/MIDIUSB/issues/44 that in its turn relies on PluggableUSB. From what I read briefly, it is the flush command in PluggableUSB that needs to wait, when using the Due hardware.

In the above example, you can replace ENABLE_WAIT with ARDUINO_SAM_DUE so it only does the wait after a flush when you compile for a Due board.

Patching for the Due in this library is a last resort, and the issue should really be addressed in PluggableUSB.h

@YuuichiAkagawa you want to raise this issue with Arduino?

YuuichiAkagawa commented 3 years ago

It's a deep-rooted problem. I use Due only for library testing. I don't necessarily need a fix.

@YANG-Mingcong Are you okay with this workaround?