T4.1 Issue Sending Midi Notes Over USB Host to Device

hfoley3

Member
Hi,

I am trying to use a Teensy 4.1 with USB Host cable to send Midi note data to another Teensy 4.1.

On the host Teensy I have the following code which has been adapted from the USBHost_t36 Interace_16x16 example (I have attempted to remove any unneeded code):


#include <MIDI.h> // access to serial (5 pin DIN) MIDI
#include <USBHost_t36.h> // access to USB MIDI devices (plugged into 2nd USB port)
#include <SerialFlash.h>

// Create the Serial MIDI ports
MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI1);
// Create the ports for USB devices plugged into Teensy's 2nd USB port (via hubs)
USBHost myusb;
USBHub hub1(myusb);
MIDIDevice midi01(myusb);
// A variable to know how long the LED has been turned on
elapsedMillis ledOnMillis;

void setup() {
Serial.begin(115200);
pinMode(13, OUTPUT); // LED pin
digitalWrite(13, LOW);
MIDI1.begin(MIDI_CHANNEL_OMNI);
delay(1500);
myusb.begin();
}

unsigned long t=0;

void loop() {
int type, note, velocity, channel, d1, d2;
bool activity = false;
// First read messages from the 6 Serial MIDI IN ports
if (MIDI1.read()) {
activity = true;
byte type = MIDI1.getType();
note = MIDI1.getData1();
velocity = MIDI1.getData2();
channel = MIDI1.getChannel();
if (velocity > 0) {
Serial.println(String("Note On: ch=") + channel + ", note=" + note + ", velocity=" + velocity);
midi01.sendNoteOn(note, velocity, channel);
} else {
Serial.println(String("Note Off: ch=") + channel + ", note=" + note);
midi01.sendNoteOff(note, velocity, channel);
}
}
// blink the LED when any activity has happened
if (activity) {
digitalWriteFast(13, HIGH); // LED on
ledOnMillis = 0;
}
if (ledOnMillis > 15) {
digitalWriteFast(13, LOW); // LED off
}

}



On the second Teensy 4.1, the one that is to receive Midi data, I have the following code, which blinks on receiving Midi messages:


// USB MIDI receive example, Note on/off -> LED on/off
// contributed by Alessandro Fasan
int ledPin = 13;

void OnNoteOn(byte channel, byte note, byte velocity) {
digitalWrite(ledPin, HIGH); // Any Note-On turns on LED
Serial.println("noton");
Serial.println(note);
Serial.println(velocity);
}

void OnNoteOff(byte channel, byte note, byte velocity) {
digitalWrite(ledPin, LOW); // Any Note-Off turns off LED
Serial.println("notoff");
}

void setup() {
Serial.begin(9600); // USB is always 12 Mbit/sec
Serial.println("Hello, this is your synth speaking...");
pinMode(ledPin, OUTPUT);
usbMIDI.setHandleNoteOff(OnNoteOff);
usbMIDI.setHandleNoteOn(OnNoteOn) ;
digitalWrite(ledPin, HIGH);
delay(400); // Blink LED once at startup
digitalWrite(ledPin, LOW);
}

void loop() {
usbMIDI.read();
}


The host Teensy's LED does blink when receiving Midi, both from the PC and 5 Pin. It is also is able to print the correct Midi Messages to the Serial Monitor.
And when the second Teensy is connected to the PC it's LED blinks when receiving Midi.

I've been scratching my head all day trying to work out the issue, trying all the usual troubleshooting techniques.

Thanks for any help you are able to give. :D
(Apologies if my description of the issue is not adequate.)
 
I believe you missed myusb.Task() inside your loop() in the "host" code. Also if you could wrap your source code in code tags next time, it would be a lot easier to read.
 
I believe you missed myusb.Task() inside your loop() in the "host" code. Also if you could wrap your source code in code tags next time, it would be a lot easier to read.

Hi Wcalvert, thank you for the suggestion, I will try that in the morning. Yeah apologies for the ugly code format, I wasn't sure how to attach it nicely, will do next time.

Thanks again,
Harry
 
Unfortunately, it is still not working.

I am completely confused now as to what the issue is.
I have been testing the USB MIDI host with odd results so far. I have been unable to send Midi in either directions between the two Teensy Boards, however when I plug my Arturia Keystep Midi Keyboard into the USB Host I am able to receive midi from the keyboard into my teensy.

To give an update on what is currently working and what is not:

> I have 2 Teensy 4.1s.
> Teensy "A" has the USB Host cable mounted to it.
> Teensy A also has 5 pin Midi IN (Which is fully working).
> The code on Teensy A is the "Interface_16x16" example from the USBHost_t36.h library

> Teensy "B" is plugged into the host cable
> The code I have on Teensy B at the moment is to test can I receive MIDI from Teensy B over USB Host into Teensy A, which is as follows:

Code:
void setup() {
  pinMode(13, OUTPUT); // LED pin
  digitalWrite(13, LOW);
}

void loop() {
  usbMIDI.sendNoteOn(60, 99, 1);
  digitalWriteFast(13, HIGH);
  delay(1000);
  usbMIDI.sendNoteOff(60, 99, 1);
  digitalWriteFast(13, LOW);
  delay(1000);
}

I have tested the code on Teensy B using Puredata and it is successfully sending MIDI data over USB.

Has anyone any suggestions?

What would be amazing help is if someone has a short script, that they know works, to send a single arbitrary midi message from the USB Host Teensy (A) to the receiving Teensy (B).
 
Very difficult to follow your post regarding who's doing the sending and who's doing the receiving, but it appears you missed usbMIDI.read(); inside the loop() of the code snippet. It may also be better not to use delay() in your loop() because it might (?) block execution of other code that we can't see.
 
Apologies for the confusion.
To clear it up, the end goal is to send MIDI over USB Host from Teensy A to Teensy B.
So far I have been unable to do that,
so I am currently testing if I can send MIDI in the other direction, from B to A, to try to establish where the issue is. This is also why I don't have usbMIDI.read() in the code above as I am currently only testing to see if Teensy A can receive MIDI from Teensy B.

Picture for clarity

IMG_20210427_183528.jpg
 

Attachments

  • IMG_20210427_183528.jpg
    IMG_20210427_183528.jpg
    102.4 KB · Views: 85
Host code:

Code:
#include <Arduino.h>
#include "USBHost_t36.h"

USBHost usbHost;
MIDIDevice usbHostMidi(usbHost);
elapsedMillis wait;

void setup() {
    usbHost.begin();
}

void loop() {
    // USB host
    usbHost.Task();
    usbHostMidi.read();

    // send something every 1 second
    if(wait > 1000) {
        usbHostMidi.sendNoteOn(10, 100, 0);
        wait = 0;
    }
}

Receive/client code:
Code:
#include <Arduino.h>

bool led = false;

void OnNoteOn(byte channel, byte note, byte velocity) {
    digitalWriteFast(13, led);
    led = !led;
}

void OnNoteOff(byte channel, byte note, byte velocity) {
    // do something here
}

void setup() {
    pinMode(13, OUTPUT);
    usbMIDI.setHandleNoteOff(OnNoteOff);
    usbMIDI.setHandleNoteOn(OnNoteOn);
}

void loop() {
    // USB device
    usbMIDI.read();
}

You should see the built in LED blinking on the client/receiver. Tested it here and it works.
 
Thanks very much for that.
Unfortunately it did not work for me. What setting do you have "USB Type: " at?
I have the 4 pin version of the host cable as opposed to the 5 pin version, I had read that this should not be an issue, but just to double check, is it?

IMG_20210427_195623.jpg
 
I'm using platformio, so my setting is "build_flags = -DUSB_MIDI_SERIAL". I suppose you're using the arduino IDE, so I can't tell you where/what to select there. However, if it's not selected correctly, the code will not even compile, so I doubt very much that's the issue.

The two USB Host ground pins are tied together on the Teensy side, so I doubt very much that's the issue... unless Paul chimes in to correct me there.

That really only leaves the USB cable itself as the culprit. I don't know what else to suggest, sorry.

*by the way I'm just a regular user, not an official PJRC person, even though I'm replying in the tech support forum.
 
Last edited:
Yeah I'm at a loss.
I was able to send MIDI over the USB cable to the Host from my Midi Keyboard though so the cable really shouldn't be the issue but who knows.

Thanks for all your help.
 
Are you sure the USB cable plugged into the client T4.1 is a data+power USB cable? I don't mean the 4 pin host cable, I mean the device cable.

On 2 different occasions I've had power-only cables sneak onto my bench and wasted a bunch of my time trying to figure out why stuff wasn't working.

Other than that, how are you providing 5V to this whole system? The power could be sagging with two 4.1s coming up simultaneously.

You could experiment with adding a delay in the host code before the "usbHost.begin();" line to try mitigating any power issues.
 
I've tried the code in #7 and it doesn't work for me either. I've added code to flash the LED at startup in the receiver so that I know that it is at least powering up and that I'm using a data cable.

Pete
 
Interesting.

My receiver was actually a T3.6 because that's what I had handy.

I will try to scrounge up a T4 to use as the receiver, but gotta work now.
 
Yeah I also experimented with a delay before usbHost.begin() but no joy either. I'm going to look into using external power instead of USB.
 
I connected the receiving T4.1 directly to Windows and sent MIDI Note On messages to it using MIDI_OX. It works, so the receiver code and T4.1 are fine.

Pete
 
Could you try powering the receiving T4.1 from its own 5V supply? In other words, only D+, D-, and Gnd should be connected between host and receiver.

The reason I suggest this is I don't know the characteristics of the 5V USB supply on the host T4.1, so perhaps it's not sufficient for powering another T4.1.
 
i know this has been a long time ago, but your error most likely is that you need a
Code:
USBHost usbHost;
MIDIDevice_BigBuffer usbHostMidi(usbHost); //<- to host a 480mb device you need the bigbuffer object...
elapsedMillis wait;
 
Back
Top