Closed jspx-projects closed 3 years ago
So I will use that library now.
OK
So are you interested in making it work? Do you need any support or more info? I think it is not customary to close a bug report like that...
You made up your mind to use the underlying library ('So I will use that library now') - fine with me.
I have no Arduino Zero here to test with, but this library does not call any other methods than the one in the MIDIUSBwrite
example. How about you add some Serial.println
s in the code and see what you get.
Happy to re-open the issue
I investigated a little the example NoteOnOffEverySecond. I had to change Serial to SerialUSB, and then I got the message Arduino Ready at the USB serial console. Using amidi -p hw:4,0,0 --dump I see that the note on and note off commands are sent over USB, so that works. However, I see no more output on the serial monitor. This means that the call back functions are not triggered. I changed the MIDI.read() call in loop() to this:
byte input;
if( (input=MIDI.read()) )
{
Serial.print("MIDI.read returned ");Serial.println(input, HEX);
}
And this does not print anything. So if I understand the use of MIDI.read correctly this means that no MIDI is being read. I did not investigate this any further, but I hope this information is useful. Can you confirm that this example runs for you, and on what hardware?
I have a hardtime understanding your setup, so let me show you my development setup:
A Leonardo with a DIN MIDI shield, the Leonardo is connected to the computer via the USB cable. A Roland UM-One connecting the DIN connectors to the DIN MIDI shield, the USB to the computer.
The notes send from te Leonardo, come in MIDI-OX via the UM-One and the notes send from the UM-One and received in the Leonardo debug window.
My setup is the same as yours, see photos, I also use the Roland UM-One. To the left you see my prototype, which can scan 4 complete organ keyboards 3 times per ms, and also read some analog inputs for volume and expression pedals. It outputs to MIDI DIN5 and USB and forwards everything from DIN5 MIDI in to DIN5 MIDI out and MIDI USB. The MCU board plugged into it is the SAMD21 MINI board I am using with board profile Arduino Zero (Native USB) in Arduino environment.
See the second photo with the results I mentioned in my previous post. I use the test program NoteOnOffEverySecond modified to work on my hardware (copied at the end of this post). Terminal on bottom-left shows MIDI USB output to be OK (command: amidi -p hw:3,0,0 --dump, I use Linux). Arduino serial console only shows "Arduino ready" so no messages received. In this test, the UM-Ono is not used since we are testing only USB MIDI. Just to be completely clear: I expect the test program to work only on USB MIDI and also to react to the messages it sends itself.
I am beginning to suspect that for this board MIDI.read() is looking at the wrong port, if such a thing is possible using USB MIDI.
I hope this helps, let me know if you have any other questions.
#include <USB-MIDI.h>
USBMIDI_CREATE_DEFAULT_INSTANCE();
#define Serial SerialUSB
unsigned long t1 = millis();
void handleNoteOn(byte inChannel, byte inNumber, byte inVelocity)
{
Serial.print("NoteOn ");
Serial.print(inNumber);
Serial.print("\tvelocity: ");
Serial.println(inVelocity);
}
void handleNoteOff(byte inChannel, byte inNumber, byte inVelocity)
{
Serial.print("NoteOff ");
Serial.print(inNumber);
Serial.print("\tvelocity: ");
Serial.println(inVelocity);
}
void setup()
{
Serial.begin(115200);
while (!Serial);
MIDI.begin();
MIDI.setHandleNoteOn(handleNoteOn);
MIDI.setHandleNoteOff(handleNoteOff);
Serial.println("Arduino ready.");
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void loop()
{
byte input;
if( (input=MIDI.read()) )
{
Serial.print("MIDI.read returned ");Serial.println(input, HEX);
}
if ((millis() - t1) > 500)
{
t1 = millis();
MIDI.sendNoteOn(27, 55, 1);
MIDI.sendNoteOff(27, 55, 1);
}
}
I did an experiment. The test program is running and I use various sources of MIDI signals.
Conclusion: MIDI.read is not reliable. This experiment gets me to the point where the program reacts to messages directly sent to the "Arduino Zero MIDI" port, but sporadically.
Using my own keyboard reading program, and the MIDIUSB library, I can send the MIDI file to the port of the ARDUINO ZERO MIDI and everything is echoed without delay to the serial console. I think this really shows that something is going on in the layer on top of the MIDIUSB. For now this is the end of my input, I hope it is useful.
It outputs to MIDI DIN5 and USB and forwards everything from DIN5 MIDI in to DIN5 MIDI out and MIDI USB. The MCU board plugged into it is the SAMD21 MINI board I am using with board profile Arduino Zero (Native USB) in Arduino environment.
I still struggle to understand your topology and the photos don't help. Your program (with the correction i mention below) works like a charm in my setup (and removing the #define Serial SerialUSB
).
I'm pretty sure the issue has to do with your setup (MIDI DIN5, USB, MCU, SAMD21), try to simplify to the bare minimum. Remove the callback and just send 1 note every 500ms and see where the note ends up.
Note:
byte input;
if( (input=MIDI.read()) )
{
Serial.print("MIDI.read returned ");Serial.println(input, HEX);
}
MIDI.read() returns a boolean, data come in or not. So printing input will only give you 1 or 0. The callbacks are the way to get informed about incoming MIDI commands. So:
if( (MIDI.read()) )
{
Serial.println("MIDI activity");
}
Hello. I already know that sending notes work. They are received correctly on the MIDI port of the ARDUINO ZERO MIDI device, as shown by the screenshot. So I do not need to test that any further. Wrt the boolean: thanks for the info. Your change will not influence the rest of the program. but indeed you prevent needlessly printing out 1.
Can you indicate what the behavior of the test program is in your case? Are the callbacks triggered by the MIDI noteon/noteoff that is sent by the program itself? Since there is no documentation in the examples it is not at all clear what the expected behavior is...
Topology: MCU board connected via USB to computer. Roland UM-One connected to different USB port of same computer. Also Roland UM-One connected to DIN5 MIDI in and out of my prototype. Exactly your setup, no?
I also unplugged the two DIN5 connectors and the UM-One, so the setup is just my prototype over USB to the computer, and forget all the rest. MIDI sent correctly, but no MIDI received, so still does not work. So forget about the UM-One and the physical MIDI connectors, they are not related to the problem.
IMHU My earlier post [(https://github.com/lathoub/Arduino-USBMIDI/issues/5#issuecomment-752960723)] describes the problem clearly. That should be the base for further analysis. I think we need to think about differences in the Arduino core of my and your boards. What could be different and cause this problem?
EDIT: Unrelated information / perhaps useful in some way FYI: I used the setup to demonstrate that my prototype can forward everything it receives on DIN5 in to both DIN5 out and USB out. Further I demonstrated that the prototype generates MIDI correctly (key presses and volume changes) and sends it both to DIN5 out and USB correctly. The only thing I still need to implement is also to forward MIDI received over USB to DIN5 out. All of this works perfectly, as long as I use the MIDIUSB library.
EDIT:deleted incorrect part
OK - understanding that sending works.
Here is how i get receiving MIDI messages to work:
Hardware: Leonardo USB connected to computer (no MIDI shields or anything else). Arduino: open the AllEvents example, compile/upload and open the serial monitor On a Windows box: open MIDI-OX, select "Arduino Leonardo" [1] from the output devices list, and output MIDI notes in MIDI-OX - they show in the Arduino Serial monitor.
I don't use linux, don't what the equivalent is for MIDI-OX
Since there is no documentation in the examples it is not at all clear what the expected behavior is...
I look forward to your documentation suggestions, after we get this to work.
[1] the underlying USBMIDI library takes all care of this
I did as you asked. I do not have an Arduino Leonardo, so I have to use board profile "Arduino zero (Native USB)". As expected, the result is the same as before.
Sending is OK. I can monitor the MIDI that is sent: they are noteon and noteoff directly after each other, with a bunch of 00 00 messages in between, presumably the clock signals sent by the example.
Receiving is not OK. 2a. I do not receive any MIDI generated by the example itself - my question to you still is: should I receive them? 2b. When I play a MIDI file the program receives something, but the results are erratic. The Arduino serial monitor shows this:
ProgramChange from channel: 1, number: 1
ControlChange from channel: 1, number: 7, value: 127
ControlChange from channel: 1, number: 10, value: 64
(these are the first three MIDI messages I referred to in my earlier posts). Then after 36 seconds of waiting the Serial monitor shows more notes and program changes for about 24 seconds. Then a pause, and again some notes after the pause.
If I start the song again - same pattern. The three program changes, wait for 36 seconds, only then see some more notes and program changes etc.
So my conclusion is the same as before, MIDI.read works erratically.
ps these are the linux commands I use to play a song: list all MIDI ports:
aplaymidi -l
Port Client name Port name
14:0 Midi Through Midi Through Port-0
20:0 UM-ONE UM-ONE MIDI 1
28:0 Arduino Zero Arduino Zero MIDI 1
Send a MIDI file to the Arduino MIDI port:
aplaymidi -p 28:0 ./Disney_Themes_-_Fantasmic.mid
Just a random MIDI file I found on the internet.
If I play the MIDI file like this and use my own software (using USBMIDI directly) everything works perfectly. I see the same song "playing" on the Arduino serial monitor really fast, no delays.
And these are the commands I use to monitor the raw data on the MIDI ports (in HEX): list MIDI devices:
amidi -l
Dir Device Name
IO hw:1,0,0 UM-ONE MIDI 1
IO hw:3,0,0 Arduino Zero MIDI 1
monitor MIDI port
amidi -p hw:3,0,0 --dump
put in some 'poor-man debugging' in the source code:
add
Serial.println(mPacket);
This library is a thin rapper over USBMIDI on top of the MIDI-library, with only 1 MidiUSB.read();
See what the Serial.println
does
(just checking: you do not have old versions of the MIDI-library, USBMIDI or Arduino-USBMIDI in your path)
I had to do it like this (in my file, the line was 139, not 137):
mPacket = MidiUSB.read();
SerialUSB.print(mPacket.header, HEX);
SerialUSB.print(mPacket.byte1, HEX);
SerialUSB.print(mPacket.byte2, HEX);
SerialUSB.println(mPacket.byte3, HEX);
And the result is this (all zeros):
...
0000
0000
...
I installed USB-MIDI and MIDIUSB together last week. Just upgraded MIDIUSB to 1.05. Not sure when I installed MIDI_library. Arduino output says this:
Linking everything together...
/home/john/.arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/bin/arm-none-eabi-g++ -L/tmp/arduino_build_640052 -O2 -Wl,--gc-sections -save-temps -T/home/john/.arduino15/packages/arduino/hardware/samd/1.8.9/variants/arduino_zero/linker_scripts/gcc/flash_with_bootloader.ld -Wl,-Map,/tmp/arduino_build_640052/AllEvents.ino.map --specs=nano.specs --specs=nosys.specs -mcpu=cortex-m0plus -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -o /tmp/arduino_build_640052/AllEvents.ino.elf /tmp/arduino_build_640052/sketch/AllEvents.ino.cpp.o /tmp/arduino_build_640052/libraries/MIDI_Library/MIDI.cpp.o /tmp/arduino_build_640052/libraries/MIDIUSB/MIDIUSB.cpp.o /tmp/arduino_build_640052/core/variant.cpp.o -Wl,--start-group -L/home/john/.arduino15/packages/arduino/tools/CMSIS/4.5.0/CMSIS/Lib/GCC/ -larm_cortexM0l_math -lm /tmp/arduino_build_640052/../arduino_cache_616852/core/core_arduino_samd_arduino_zero_native_1f31e3723d891ad684fba1f25f33f1e5.a -Wl,--end-group
/home/john/.arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/bin/arm-none-eabi-objcopy -O binary /tmp/arduino_build_640052/AllEvents.ino.elf /tmp/arduino_build_640052/AllEvents.ino.bin
/home/john/.arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/bin/arm-none-eabi-objcopy -O ihex -R .eeprom /tmp/arduino_build_640052/AllEvents.ino.elf /tmp/arduino_build_640052/AllEvents.ino.hex
Using library USB-MIDI at version 1.1.2 in folder: /home/john/Arduino/libraries/USB-MIDI
Using library MIDI_Library at version 5.0.2 in folder: /home/john/Arduino/libraries/MIDI_Library
Using library MIDIUSB at version 1.0.5 in folder: /home/john/Arduino/libraries/MIDIUSB
I will reply again tomorrow, I already wish you a happy new year :-) :+1:
ps I get this warning (not important, but still)
/tmp/arduino_modified_sketch_881307/AllEvents.ino: In function 'void OnSystemExclusive(byte*, unsigned int)':
/tmp/arduino_modified_sketch_881307/AllEvents.ino:133:38: warning: unused parameter 'array' [-Wunused-parameter]
static void OnSystemExclusive(byte * array, unsigned size) {
^~~~~
/tmp/arduino_modified_sketch_881307/AllEvents.ino:133:54: warning: unused parameter 'size' [-Wunused-parameter]
static void OnSystemExclusive(byte * array, unsigned size) {
[EDIT: included spaces in the print statements so you can distinguish the nibbles in each byte]
I now made some progress. I changed the location of the print statements to this:
mPacket = MidiUSB.read();
if (mPacket.header != 0) {
//
SerialUSB.print(mPacket.header, HEX);SerialUSB.print(" ");
SerialUSB.print(mPacket.byte1, HEX);SerialUSB.print(" ");
SerialUSB.print(mPacket.byte2, HEX);SerialUSB.print(" ");
SerialUSB.println(mPacket.byte3, HEX);
If I now play a MIDI file to my boards USB MIDI port, I can see a continuous stream of output, so I think that the complete MIDI file is received: the MidiUSB.read() works. But not all received notes are "received" by the test program
Here is the first part of the serial monitor output, it shows that after the first three MIDI notes, a lot are received but do not result in statement printed to the serial monitor, so not actually received by the test program.
C C0 1 0
ProgramChange from channel: 1, number: 1
B B0 7 7F
ControlChange from channel: 1, number: 7, value: 127
B B0 A 40
ControlChange from channel: 1, number: 10, value: 64
B B1 0 0
B B1 20 0
C C1 3C 0
B B1 7 7F
B B1 A 40
B B2 0 0
B B2 20 0
C C2 3D 0
B B2 7 7F
B B2 A 40
B B3 0 0
B B3 20 0
C C3 3E 0
B B3 7 7F
B B3 A 40
B B4 0 0
B B4 20 0
C C4 21 0
B B4 7 7F
B B4 A 40
B B5 0 0
Please find attached the complete serial monitor output. It confirms my earlier experiments: there are only a few sections (with large pauses in between) where the mPackets that were received result in MIDI "received" by the test program. I hope this allows you to form a hypothesis of any problems.
Let me know if I can do anything more :-)
Lets see what is fed to the underlying MIDI parser, add a SerialUSB.print(byte, HEX);
just before return byte;
Then also add an errorHandler
void handleError(int8_t err)
{
SerialUSB.print(err, HEX);
}
...
void setup()
{
...
MIDI.setHandleError(handleError);
What does the input stream look like?
Here is the requested output of again the whole song. It seems again the same pattern and I do not see any err from the error handler. I made it like this
void handleError(int8_t err)
{
SerialUSB.print("Error ");
SerialUSB.println(err, HEX);
}
What does the input stream look like? (what do you send to the USB device)
I was able to find a hypothesis for the problem. The Disney_Themes_-_Fantasmic.mid
on the internet plays a song on all midi channels . Your application only listens to channel 1 (not passing any argument to MIDI.begin() will set the channel to 1)
Solution:
MIDI.begin(MIDI_CHANNEL_OMNI );
Yes, this modification allows "all_events.ino" to receive the complete MIDI from the file now, including the channel number! So this solves the problem for that test program. I still suggest adding some documentation to the various test programs in the comments at the start and modify the test program so it listens on all channels.
I will now create a new version of my own program using the USB-MIDI library instead of MIDIUSB, and report back on that.
I still suggest adding some documentation to the various test programs in the comments at the start and modify the test program so it listens on all channels.
I look forward to your contributions to this open source project
IThe library itself is ready, but I will try to document the examples a bit. The source of my own confusion is the example NoteOnOffEverySec. I expected the noteOn and NoteOff sent by the program to be also received by the program, which is not the case.
Ok, it was an error on my side, caused by misinterpretation of the example file.
Reproduce like this: Install MIDI and USB-MIDI, the latter pulls in also MIDIUSB. Load the example NoteOnOffEverySecond. The computer connected to the MCU via USB detects MIDI device Arduino zero, but no MIDI is received, and no midi notes are received by the MCU. This example works perfectly: MIDIUSBwrite, it uses the MIDIUSB library. So I will use that library now.
Device used: SAMD21 MINI, using profile "Arduino-zero (native USB).