USB Midi hangs when no

Status
Not open for further replies.

ftrias

Well-known member
I have a code snipet that sends notes to usbMIDI and uses Serial.print() to follow the progress.

Code:
void setup() {
  Serial.begin(57600);
  delay(3000);
  Serial.println("setup");
}

const int maxv = 127;

void loop() {
  static uint8_t note = 65;
  note++;
  Serial.println("start");
  usbMIDI.sendNoteOn(note, 64, 1);
  for(int vol=0;vol<=maxv;vol++) {
    //Serial.println(vol);
    usbMIDI.sendControlChange(7, vol, 1);
    delay(10);
  }  
  Serial.println("mid");
  for(int vol=maxv;vol>0;vol--) {
    //Serial.println(vol);
    usbMIDI.sendControlChange(7, vol, 1);
    delay(10);
  }   
  Serial.println("sent");
  delay(10);
}

I upload the program and open the debugging window. I expect it to print

Code:
setup
start
mid
sent
start
....and so forth

Instead I see

Code:
setup
start

And then nothing. The teensy apparently hangs.

If I then run a program that listens to MIDI, then the code continues running and everything is fine.

If I uncomment the "Serial.println(vol)" lines, then the program continues running and the output is as expected.

It's puzzling. Anyone else seen this? I am building on a Mac. Any ideas of how to fix this problem? Ideally, I don't want to put Serial.print statements all over the program.

As a second question, is there any way to know if a program is actually connected to MIDI?
 
And then nothing. The teensy apparently hangs.

If I then run a program that listens to MIDI, then the code continues running and everything is fine.

Well yes, of course. Your code sends 100 MIDI messages per second. If nothing is receiving on the Mac side, that will pretty quickly fill up all the available outbound USB buffers.
 
Yes. That does seem logical. But I was puzzled why adding Serial.print() would make it work.

I experimented a bit more and may have found a few clues.

Code:
void setup() {
  Serial.begin(57600);
  delay(3000);
  Serial.println("setup");
}

void loop() {
  Serial.println("start");
  for(int vol=0;vol<11;vol++) {
    usbMIDI.sendControlChange(7, vol, 1);
    delay(100);
  }  
  Serial.println("sent");
  delay(100);
}

The above program hangs after displaying "setup" and then "start". However, if I remove the "delay(100)" line, it will keep running, albeit very fast. Also, if I change "vol<11" to "vol<10", but keep the delay() it will run fine.

But what will really solve this for me is knowing whether or not the MIDI messages are being consumed. If they are not, I can skip sending them. Is there a way to know?

I am building a project that uses MIDI to send feedback while processing. If MIDI is not being listened to, it still needs to keep processing.
 
I started browsing through the source code, which is very clear and organized despite it's complexity (well done!) and may have answered my question. For the sake of completeness and getting feedback, I'll post it here. I need to look at the result of "usb_tx_packet_count(MIDI_TX_ENDPOINT);" defined in usb_dev.h.

The reason why it works without the "delay()" but fails with "delay()" is still baffling.

So my test code now looks like this and works.

Code:
#include <usb_dev.h>
#include <usb_desc.h>

void setup() {
  Serial.begin(57600);
  delay(3000);
  Serial.println("setup");
}

void loop() {
  Serial.println("start");
  for(int vol=0;vol<11;vol++) {
    int c = usb_tx_packet_count(MIDI_TX_ENDPOINT);
    if (c<2) { // receiving, so send more
      usbMIDI.sendControlChange(7, vol, 1);
    }
    delay(100);
  }  
  Serial.println("done");
  delay(100);
}
 
Status
Not open for further replies.
Back
Top