-
Notifications
You must be signed in to change notification settings - Fork 130
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rp2040 PICO arduino tinyUSB midi example midi_test crashes when simultaneously receiving and sending messages at (not too fast) speed #238
Comments
I have now tried this with windows 10 and an macOS and I got the same results. |
Hello, |
I tried this again with 1.18.3 and got the same results. |
late response, though since I am not familiar with MIDI, I need help with this step of reproducing. Please be specific on which app and which step you use to send clock ticks. It would be better if you are using an app that could run on ubuntu since that is my PC. |
@hathach I have some python code (3.10, works with pygame) on my Rpi at home. I will take a look tomorrow when i come home. But I don't think the pygame supports midi ticks |
In the bug report above i linked 2 files.
midi_test.txt needs renaming to midi_test.ino and test1.txt needs renaming to test1.html It dosen't really matter what the midi events are. There is nothing special about clock ticks. I have tried noteon, noteoff, cc, clock ticks, small sysex messages, all types of midi messages. All with the same result. As I said, However, if i try to send AND receive at the same time at even a slow rate of 50 messages combined per second then the pico eventually crashes. If i send AND receive at a rate of 600 cumulative per second the pico crashes within seconds. It dosent matter what type of midi messages are involved. |
I'm able to reproduce this error, it seems that if I disable the Serial printing, it takes a while longer to crash. In a project I'm working on, I get a crash quite quickly if I send a MIDI sysex message to the USB MIDI port just after I print something to Serial. If I comment out the serial printing, the project doesn't crash. Something related to buffers maybe? |
NOTE/UPDATE: Disregard my example below, with Serial.flush() after the serial print, the example works flawlessly so it is not related to the original bug report. Ok, I made a simple example that prints to serial and then sends a MIDI sysex message every 100ms, this gives me a crash after just a few seconds every time. If I disable the serial printing, there seems to be no crash. Here is the code you can try (you just need to monitor the serial port): #include <Arduino.h>
#include <Adafruit_TinyUSB.h>
#include <MIDI.h>
Adafruit_USBD_MIDI usb_midi;
MIDI_CREATE_INSTANCE(Adafruit_USBD_MIDI, usb_midi, MIDI);
// Sysex message
uint8_t sysex[9] = {0x3E, 0x00, 0x7F, 0x60, 0x00, 0x03, 0x0C, 0x0A, 0x19};
// Buffer for serial printing
char strBuffer[40];
// Message counter
uint32_t count = 0;
void setup()
{
#if defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_RP2040)
// Manual begin() is required on core without built-in support for TinyUSB such as mbed rp2040
TinyUSB_Device_Init(0);
#endif
pinMode(LED_BUILTIN, OUTPUT);
MIDI.begin(MIDI_CHANNEL_OMNI);
Serial.begin(115200);
while( !TinyUSBDevice.mounted() ) delay(1);
}
void loop()
{
static uint32_t start_ms = 0;
if ( millis() - start_ms > 100 )
{
start_ms += 100;
sprintf(strBuffer, "%s %d", "Message count:", ++count);
// Disable the serial printing and there will be no crash, with serial printing a crash happens after just a few seconds
Serial.println(strBuffer);
MIDI.sendSysEx(9, sysex);
}
// read any new MIDI messages
MIDI.read();
} |
I can confirm that the same crash is happening to me and indeed it can be fixed by commenting out all Serial prints. Thanks for the solution MickGyver! |
I believe I've encountered the same bug while doing binary data transfer with 2 CDC serial ports. I'm using the first port for unidirectional debug prints (MCU->Host), and the second port for bidirectional binary communication. My test case has 8-16 byte Host->MCU commands being sent every few milliseconds, and the MCU responds with ~40 byte responses as soon as it parses a full command, with a rough guess of 150 bytes of debug prints per response. depending on the host command rate, the mcu will hang within 40-300 command-response iterations. I am not using the second core at all, and am not using FreeRTOS. Using a black magic debug probe, I stopped execution once the pico hung and found that it was stuck in
at line 121 in tusb.c, which calls
which is defined in mutex.h in the pico sdk. |
@Copper280z Thank you for the precise debug! Well since then it just works fine! Can anyone tell me what I did and when I will get problems? 🙈 But in my case I am not saving lives and thus this works for me! since I am not counting midi clicks I even don't care if I miss some messages.. |
Same OSAL_TIMEOUT_NORMAL workaround seems to fix my problems in #293 too -- would be great to figure out what the underlying cause is and what the real fix should be? |
Same happens to me. The OSAL_TIMEOUT_NORMAL workaround works sometimes: the same device with the same firmware works and then doesn't work, I couldn't find a pattern yet testing with a Pico and a Yamaha P45 digital piano (whose MIDI sends a lot of msgs and ticks all the time). |
Hi @hathach, here's a minimal example with instructions for reproducing the issue on Ubuntu:
amidi -l # list available MIDI devices
port=hw:1,0,0 # change accordingly
# send and receive MIDI data to/from the Pico (sometimes this command hangs)
amidi -p $port -r MIDI-veryshort-response.syx -ca -t 1 -s MIDI-veryshort-challenge.syx
# compare the received data with what we sent (other times this comparison fails)
cmp MIDI-veryshort-response.syx MIDI-veryshort-challenge.syx #include <Adafruit_TinyUSB.h>
Adafruit_USBD_MIDI usb_midi;
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
usb_midi.begin();
while(!TinyUSBDevice.mounted())
delay(1);
}
void loop() {
// Simply echo back any packets we receive
uint8_t packet[4];
if (usb_midi.readPacket(packet)) {
uint8_t retry = 3;
while (!usb_midi.writePacket(packet) && retry-- > 0)
delay(1);
}
// Blink an LED so we can see when it crashes
static auto timer = millis();
static bool state = false;
if (millis() - timer >= 500) {
digitalWrite(LED_BUILTIN, state = !state);
timer += 500;
}
} |
Please fix it. |
I am having the same problem with the Adafruit Feather RP2040 board. |
Making this simple change fixes the problem for me #293 (comment) |
Yes, it seems to be working, thanks! |
@fred-rabelo I've just took a look at #293 and I believe that changing I've posted a (long) comment on #293 about it. If you are interested in potential issues of the workaround, check it out. |
Operating System
Linux
Arduino IDE version
2.0.3
Board
PICO rp2040 from RP
ArduinoCore version
PICO/RP2040 community 2.7.0
TinyUSB Library version
release
Sketch & Compiled output (as attached txt files)
modified examples/adafruit/midi/midi_test
Added callback for handling incoming clock ticks
Output 1 byte sysex every 40 ms instead of noteon/off every 266 ms
Turned off midi thru
midi_test.txt
midi_test.ino.bin.txt
What happened ?
The sketch works if i run it without sending any midi events. ie) just letting the pico send out a sysex every 40ms.
The sketch works fine if I comment out the sendSysex in the sketch (dont send anything from PICO) and send the PICO clock ticks every 80ms.
The sketch crashes when i do both at the same time.
Sometimes it crashes within a minute...sometimes an hour.
The crash stops the PICO sending data and also stops the PICO receiving data.
A full reboot of the PICO is required.
How to reproduce ?
Upload the sketch to a RPI PICO rp2040 using arduino ide and community core.
Connect a daw or other midi producing program to the PICO and send it clock ticks at 30 bpm - 24ppq = about every 80ms.
I wrote a simple html file for testing that can be dropped onto a webMIDI compliant browser.
If you want to use that for testing then copy the below html to a file called maybe test.html and drop that onto chromium/brave/chrome/edge (probably wont work in firefox).
Note: the javascript in the html looks for a midi device called "PICO MIDI 1". Change the name if your device is named differently.
With the pico running launch or refresh the script running in the browser.
Wait for a few minutes or longer for a crash.
Here is a link to a text file called test1.txt containing the html i used for testing the PICO.
test1.txt
Rename test1.txt to test1.html and drop the file on a webmidi compliant browser to test the pico.
Debug Log
No response
Screenshots
The text was updated successfully, but these errors were encountered: