Teensy 4.1 hang up when using USBHost_t36.h with HUB to control multiple midi device

Paolo157

Member
Hello gentlemen,
I' apologize for my english,
My name is PAOLO (italian) and I am new to this forum and a novice to the USBHost_t36.h library.
I developed a midi board using a Teensy 4.1 providing 4 midi IN ad OUT (uart based) and it works very well and also run fast when I connect a midi keyboard to the USB HOST (second USB) and finally when I connect the Teensy to the PC (win10) to use DAW and VST: every things sound great all together!
BUT, when I try to use a (2.0) or (3.0) HUB the program stops 2sec after the .begin() statement if a device is already connected to the HUB.
In any case when I try to connect even a single device to the HUB after .begin has been successfully terminated, Teensy stop working and needs to be restarted.
I have tested also the examples coming from usbHost_36 library and also the code copied from the forum title [RESOLVED] Multiple MIDI devices must be defined to support connectivity thru a USB hub on T4 USBhost from Thread starter kd5rxt-mark Start date Feb 26, 2024 but it give me same results stopping the Teensy (or may be looping).

Do you have any suggestions?
Many thanks in advance.
 

Attachments

  • prova_usbHost.ino
    5.7 KB · Views: 6
  • Teensy stops after few loops.jpg
    Teensy stops after few loops.jpg
    28.5 KB · Views: 3
Probably it doesn't matter but there is a double declaration of usbMIDI.setHandleNoteOn() and usbMIDI.setHandleNoteOff().

C++:
   usbMIDI.setHandleNoteOn(handleNoteOn);  // Put only the name of the function
   usbMIDI.setHandleNoteOff(handleNoteOff);

   MIDI.setHandleNoteOn(MIDIhandleNoteOn);  // Put only the name of the function
   MIDI.setHandleNoteOff(MIDIhandleNoteOff);

   usbMIDI.setHandleNoteOn(USBhandleNoteOn);
   usbMIDI.setHandleNoteOff(USBhandleNoteOff);

Paul
 
Thanks Paul, you are right and I noticed it after posting but the problem persists even after deleting the double statement
 
Could it be that your loop is too fast and overloads the external hub?
Perhaps try to sprinkle some delays in the loop like this?
C++:
void loop(void) {
  Serial.print("loop:");Serial.println(i);
   MIDI.read();
   delay(1);
   usbMIDI.read();
   delay(1);
   usbhostMIDIa.read();
   delay(1);
   usbhostMIDIb.read();
   delay(1);
   thisUSB.Task();
   delay(1);
   i++;
}

Paul
 
Thank you: test result unchanged.
I confirm that the program works correctly when the keyboard is connected directly to usbHOST.
When I connect a HUB, now the program runs and doesn't stop after a few cycles.
BUT it suddenly stops as soon as I try to attach a Keyboard to the HUB
 
I tested both case:
test 1) 3.0 hub without ext power
test 2) 2.0 hub without ext power
test 3) 2.0 hub with ext power
same negative results.
BUT
I did a new test with interesting results:
I connected the HUB to the PC and the Teensy USB to the HUB
I connected the keyboard directly to the Teensy USBHOST
I used MIDIOX to receive notes on and off which I had sent from Teensy loop using data received from the keyboard
USB type = Serial + MIDIx16 always used
>>> Everything works normally <<<
I send same msg received from Keyboard to CABLE 0 and CABLE 1 and I see them on MIDIOX (see attachment)
So I think the problem should be investigated in the usbHost_36 library that have problems when manage an HUB for MIDI msg. May be midi protocol require several classes... ? Unfortunately I don't known midi protocol over usb.

Many thanks for your support.
 

Attachments

  • NEW_TEST.jpg
    NEW_TEST.jpg
    284.5 KB · Views: 4
So I think the problem should be investigated in the usbHost_36 library that have problems when manage an HUB for MIDI msg

I ran your program from msg #1. I made only 1 small modification to print "loop <number>" slowly because the note on/off messages scroll off screen too quickly (full code below).

Code:
  static elapsedMillis msec; // print at a reasonable pace
  if (msec > 1000) {
    msec = 0;
    Serial.print("loop:"); Serial.println(i);
    i++;
  }

I connected a USB MIDI device through a USB hub to Teensy 4.1. Here is a photo of the hardware on my desk, so you can see the hardware I used for testing.

test.jpg


I pressed the drum pad buttons many times. It always prints the note on/off messages. I was not able to reproduce any problem where the program froze or stopped responding.

screen.png


This is the exact code I tested. It is the same as msg #1 but with loop printing only 1 time per second so the note on / off messages are easy to read and screen capture.

Code:
// https://forum.pjrc.com/index.php?threads/teensy-4-1-hang-up-when-using-usbhost_t36-h-with-hub-to-control-multiple-midi-device.74966/
//
// Teensy MIDI USBhost test
//   as submitted to the Teensy forum 20240226 (https://forum.pjrc.com/index.php?threads/whether-multiple-midi-devices-work-thru-usb-hub-seems-to-be-plug-order-dependent.74561/post-339860)
//
//   - reads MIDI data & cmds from traditional MIDI, usbMIDI, or USBhost & plays the indicated note(s)
//
//  Arduino IDE Configuration:
//     Tools/Board:           "Teensy 4.0"
//     Tools/USB Type:        "Serial + MIDI"
//     Tools/CPU Speed:       "600MHz"
//     Tools/Optimize:        "Debug"
//     Tools/Keyboard Layout: "US English"
//     Tools/Port:            "COMx Serial (Teensy 4.0)"
//

#define DEBUG_NOTE_MSGS
#define DEBUG_MIDI_NOTE_MSGS
#define DEBUG_USB_MIDI_NOTE_MSGS
#define DEBUG_USBHOST_MIDI_NOTE_MSGS

#include <SPI.h>
#include <USBHost_t36.h>
#include <MIDI.h>
#include <Audio.h>

#define LOCAL_MIDI_CHANNEL_OMNI -1
int midi_channel = LOCAL_MIDI_CHANNEL_OMNI;

USBHost thisUSB;
USBHub hub1(thisUSB);
USBHub hub2(thisUSB);
USBHub hub3(thisUSB);
USBHub hub4(thisUSB);
MIDIDevice_BigBuffer usbhostMIDIa(thisUSB);
MIDIDevice_BigBuffer usbhostMIDIb(thisUSB);

MIDI_CREATE_DEFAULT_INSTANCE();
#define LED_PIN 13
// function headers
void handleNoteOff(byte channel, byte pitch, byte velocity);
void handleNoteOn(byte channel, byte pitch, byte velocity);
void loop(void);
void MIDIhandleNoteOff(byte channel, byte pitch, byte velocity);
void MIDIhandleNoteOn(byte channel, byte pitch, byte velocity);
void setup();
void USBhandleNoteOff(byte channel, byte pitch, byte velocity);
void USBhandleNoteOn(byte channel, byte pitch, byte velocity);
void usbhostMIDIahandleNoteOff(byte channel, byte pitch, byte velocity);
void usbhostMIDIahandleNoteOn(byte channel, byte pitch, byte velocity);
void usbhostMIDIbhandleNoteOff(byte channel, byte pitch, byte velocity);
void usbhostMIDIbhandleNoteOn(byte channel, byte pitch, byte velocity);
uint8_t type     = 0;
uint8_t pitch    = 0;
uint8_t velocity = 0;
uint8_t channel  = 0;
uint32_t i = 0;
// -----------------------------------------------------------------------------
void setup() {
  Serial.begin(9600);
  delay(3000);
  Serial.println("set up ...begin");
  if (CrashReport)    {
    Serial.print(CrashReport);
  }
  pinMode(LED_PIN, OUTPUT);

  usbMIDI.setHandleNoteOn(handleNoteOn);  // Put only the name of the function
  usbMIDI.setHandleNoteOff(handleNoteOff);

  MIDI.setHandleNoteOn(MIDIhandleNoteOn);  // Put only the name of the function
  MIDI.setHandleNoteOff(MIDIhandleNoteOff);

  usbMIDI.setHandleNoteOn(USBhandleNoteOn);
  usbMIDI.setHandleNoteOff(USBhandleNoteOff);

  usbhostMIDIa.setHandleNoteOn(usbhostMIDIahandleNoteOn);
  usbhostMIDIa.setHandleNoteOff(usbhostMIDIahandleNoteOff);

  usbhostMIDIb.setHandleNoteOn(usbhostMIDIbhandleNoteOn);
  usbhostMIDIb.setHandleNoteOff(usbhostMIDIbhandleNoteOff);

  // start the USBhost for MIDI inputs/devices
  Serial.println("thisUSB.begin();");
  thisUSB.begin();

  // Initiate MIDI communications, listen to all channels
  Serial.println("MIDI.begin(MIDI_CHANNEL_OMNI);");
  MIDI.begin(MIDI_CHANNEL_OMNI);
  Serial.println(" fine Set up");
}
// -----------------------------------------------------------------------------
void loop(void) {
  static elapsedMillis msec; // print at a reasonable pace
  if (msec > 1000) {
    msec = 0;
    Serial.print("loop:"); Serial.println(i);
    i++;
  }
  MIDI.read();
  usbMIDI.read();
  usbhostMIDIa.read();
  usbhostMIDIb.read();
  thisUSB.Task();

}  // loop()
// -----------------------------------------------------------------------------
void handleNoteOff(byte channel, byte pitch, byte velocity) {
  Serial.print("Note Off:             ch=");    Serial.print(channel); Serial.print("  pitch="); Serial.println(pitch);
}
void handleNoteOn(byte channel, byte pitch, byte velocity) {
  Serial.print("Note On:              ch=");  Serial.print(channel);  Serial.print("  pitch=");  Serial.print(pitch); Serial.print("  velocity="); Serial.println(velocity);
}
void MIDIhandleNoteOff(byte channel, byte pitch, byte velocity) {
  Serial.print("MIDI Note Off:             ch=");  Serial.print(channel); Serial.print("  pitch=");  Serial.println(pitch);
}
void MIDIhandleNoteOn(byte channel, byte pitch, byte velocity) {
  Serial.print("MIDI Note On:              ch=");  Serial.print(channel);  Serial.print("  pitch="); Serial.print(pitch);  Serial.print("  velocity="); Serial.println(velocity);
}
void USBhandleNoteOff(byte channel, byte pitch, byte velocity) {
  Serial.print("USB MIDI Note Off:             ch="); Serial.print(channel);  Serial.print("  pitch=");  Serial.println(pitch);
}
void USBhandleNoteOn(byte channel, byte pitch, byte velocity) {
  Serial.print("USB MIDI Note On:              ch=");    Serial.print(channel);   Serial.print("  pitch=");   Serial.print(pitch);   Serial.print("  velocity=");   Serial.println(velocity);
}
void usbhostMIDIahandleNoteOff(byte channel, byte pitch, byte velocity) {
  Serial.print("USBhost MIDI(a) Note Off:             ch=");  Serial.print("0");  Serial.print(channel);   Serial.print("  pitch=");  Serial.println(pitch);
}
void usbhostMIDIahandleNoteOn(byte channel, byte pitch, byte velocity) {
  Serial.print("USBhost MIDI(a) Note On:              ch=");  Serial.print(channel);  Serial.print("  pitch="); Serial.print(pitch);  Serial.print("  velocity="); Serial.println(velocity);
}
void usbhostMIDIbhandleNoteOff(byte channel, byte pitch, byte velocity) {
  Serial.print("USBhost MIDI(b) Note Off:             ch=");  Serial.print("0");  Serial.print(channel);   Serial.print("  pitch=");  Serial.println(pitch);
}
void usbhostMIDIbhandleNoteOn(byte channel, byte pitch, byte velocity) {
  Serial.print("USBhost MIDI(b) Note On:              ch=");  Serial.print(channel);  Serial.print("  pitch="); Serial.print(pitch);  Serial.print("  velocity="); Serial.println(velocity);
}
// EOF PLACEHOLDER
 
Thank you a lot Paul
I 'm now testing your version of the code but still hanging the Teensy when I attach the keyboard trhu the HUB, and runs normally when keyboard is attached directly to Teensy usbHost.
Unable to understand the reason of this difference. Are there any possible difference on code inside Teensy ? Are there any different version of Teensy 4.1 ? Are you using type Serial + Midi x 16 ? Have you tried to connect a master keyboard instead of controller ?
Many thanks.
Paolo
 
Just to add some details: if I start Teensy with the HUB attached to the usbHost it runs normally and I can see printing the loop numbers but when I try to connect the keyboard it stop!
 
if I start Teensy with the HUB attached to the usbHost it runs normally and I can see printing the loop numbers but when I try to connect the keyboard it stop!

Please write more specific instructions to reproduce the problem. Which items are plugged at what time after upload? Or even better, give photos or short video with serial monitor visible.
 
OK
First I want to thank you and all the experts for your time and support.
Before sending detailed videos and photos of my problem, let me introduce my work to you with the attached files.
The files describe my hobby work and I'm sending for your curiosity but in reality it is not strictly related to the problem I am facing.
The problem is only related to Teensy usbHost connected to a musical keyboard via a USB HUB.
I'll send the problem description with associated video as soon as registration is completed.
Paolo
 

Attachments

  • MONSTER 7.pdf
    1.4 MB · Views: 7
  • TEENSY 4.1 MIDI BOARD.pdf
    452.7 KB · Views: 7
OK gentlemen
I recorded some videos: one to show the test environment and then a video for each test to show the problem:
- everything works fine if I connect a keyboard directly to the Teensy 4.1 USBHost: (see tests 01 and 04)
- the processor stops every time I connect the keyboard to an HUB previously connected to usbHost: (see tests 02 and 03)
The 3.0 hub failed when I connect the keyboard
Hub 2.0 same result (with or without external power)
Every time the processor stops responding (may be looping) and needs to be restarted.
Even if the keyboard is already connected to the hub before turning on the processor, the processor stops.
The sketch used to test is the Paul version and involves only the Teensy 4.1 board with keyboard connected directly via USB cable or via a USB HUB
I was unable to upload the videos here, so I am providing you with a link to a free website where the videos were uploaded and viewable
 
I add additional info coming from USBHost_viewer.ino in 3 situations:
1) when I plug in the viscount keyboard directly to usbHost
2) when I plug in a 2.0 HUB alone
3) when I plug in viscount keyboard to Hub
 

Attachments

  • 1 direct plugin to usbHost HIDDinfo.jpg
    1 direct plugin to usbHost HIDDinfo.jpg
    171.3 KB · Views: 3
  • 2 plug in HUB aolne HIDDinfo.jpg
    2 plug in HUB aolne HIDDinfo.jpg
    42.7 KB · Views: 5
  • 3 plugin Keyboard to HUB HIDDinfo.txt
    4.7 KB · Views: 2
@Paolo157: As an additional test point, I connected my SABRENT 4-port USB 3.0 Hub (HB-UMP3) to the USBhost port on my T4.1, with my MIDIplus AKM322 mini USB MIDI keyboard connected thru the hub. As Paul reported (and I am likewise running your sketch with his modifications included), my setup also continued to report loop numbers without interruption, as well as reporting noteOn & noteOff messages in the Serial Monitor as I operated keys on the keyboard. At this point, I would lean towards suspecting your USB hubs (can it be true that you have two different USB hubs, BOTH of which cause a similar hang-up ??). Any chance that you could try a different USB hub, maybe even the same SABRENT model that I used, as that is known to have worked ??

Sorry I don't have anything more certain to offer !!

Mark J Culross
KD5RXT
 
Thanks Mark,
I bought a new SABRENT 4 ports USB 2.0 HUB like yours (can see in the picture attached), because I had same doubt of you after having seen the tools used by Paul.
I'm testing now and it is working but some problems persist !
TEST DONE:
test 1) power off - plugin HUB to usbHOST - power on : GOOD loop number appear
test 2) power off - all portSwitch off - plugin keyboard to Hub port 1 - power on: GOOD notes on /off received when portSwitch on
test 3) power off - all portSwitch off - plugin keyboard to Hub port 2 - power on: GOOD notes on /off received when portSwitch on
test 4) power off - all portSwitch off - plugin keyboard to Hub port 3 - power on: GOOD notes on /off received when portSwitch on
test 5) power off - port 1 Switch ON - plugin keyboard to Hub port 3 - power on : GOOD notes on /off received
test 6) equal test 5) but port 2: same results
test 7) equal test 5) but port 3: same results
Anomalous behaviours:
test 8) power off - all portSwitch off - plugin keyboard to Hub port 4 - power on: FAILED: Teensy runs loops but stops as soon as I push the port 4 switch ON.
test 9) power off - port 4 Switch ON - plugin keyboard to Hub port 4 - power on: FAILED: Teensy stops before loop: none loop numbers appear
test 10) equal test 5) but port 4: FAILED: Teensy stops before loop: loops number do not appear.
test 11) hot plug in / out stops the Teesny or inhibits Teensy to receive messages from any ports
COMPLESX test 12) :
  • power off - all portSwitch off - plugin keyboard to Hub port 1 - power on switch port1 ON: GOOD switch port1 Off ;
  • THEN plug in keyboard from port 1 to port 2 : GOOD even with switch port 2 off ;
  • THEN plugin keyboard from port 2 to port 3 : GOOD even if switch port 3 is off;
  • THEN plug in keyboard from port 3 to port 4 : FAILED Teensy do not receive message and after none of the ports is able to receive message even if loop runs.
Conclusions:
  • HOT plug in / out generate potential random behaviour even on other ports;
  • seems Teensy not able to manage port 4
 

Attachments

  • IMG_8436.JPEG
    IMG_8436.JPEG
    254.6 KB · Views: 3
Last edited:
@Paolo157: I have no scientific reason to suggest the following . . . just a hunch . . . maybe the keyboard [manufacturer/model ??] is registering/acting as more than a single MIDI device . . . this has been reported behavior of some keyboards in other unrelated threads. See what happens if/when you define & initialize a couple more MIDIDevice_BigBuffer devices over & above the two that you already have. In the thread where you found my test sketch, you'll recall that I described very strange behavior that seemed to indicate (in all fairness, it was certainly due to my own mistake) an odd dependency on the order in which devices were connected. Since you, likewise, seem to have something that appears to be illogical, it shouldn't/wouldn't hurt to try the not-so-obvious to see if that might somehow help . . .

Mark J Culross
KD5RXT
 
Also, just to be complete, which version of TeensyDuino are you using ?? If you're not already using TD1.59, it probably wouldn't hurt to update to the latest, just to be sure.

Mark J Culross
KD5RXT
 
Thanks so much Marco,
I'm using version 1.59 but this is my first time using Teensy.
In any case this solution based on the new SABRENT HUB works quite well for my needs.
I think it might be nice to have a tested solution that allows you to use the Teensy 4.1 with any USB Hub and be able to connect up to 16 midi devices together, although in this case I don't know if the messages could be handled without latency or other problems due to amount of data.

Thank you all for your support.
I'm really happy !
 
SABRENT 4 Port USB 3.0 Hub with Individual LED Lit Power Switches, Includes 5V/2.5A Power Adapter (HB-UMP3)
 
Back
Top