Teensy 4.1 as USB MIDI host

I am trying to connect a MIDI keyboard using USB port on top of the Teensy 4.1 board. And here is the code I have.
C++:
#include <Arduino.h>
#include <Wire.h>
#include <SPI.h>
#include <Audio.h>
#include "USBHost_t36.h"


// -------- Audio shield (minimal bring-up) --------
AudioControlSGTL5000 sgtl5000_1;


// -------- USB host (MIDI) objects --------
USBHost myusb;
USBHub  hub1(myusb);              // optional hub support
USBHub  hub2(myusb);
MIDIDevice_BigBuffer midi1(myusb);


// -------- MIDI callback prototypes --------
void handleNoteOn(byte channel, byte note, byte velocity);
void handleNoteOff(byte channel, byte note, byte velocity);
void handleControlChange(byte channel, byte control, byte value);
void handleProgramChange(byte channel, byte program);
void handlePitchBend(byte channel, int bend);
void handleAfterTouchPoly(byte channel, byte note, byte pressure);
void handleAfterTouchChannel(byte channel, byte pressure);
void handleSystemExclusive(const uint8_t *data, uint16_t length, bool lastChunk);


void setup() {
  Serial.begin(115200);
  while (!Serial && millis() < 1500) {
    ; // wait for USB serial
  }


  // Bring up the audio shield (keeps I2S clocking happy when the board is attached)
  AudioMemory(12);
  sgtl5000_1.enable();
  sgtl5000_1.volume(0.5f);


  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);


  Serial.println(F("[USB-MIDI] Initializing USB host..."));
  myusb.begin();  // powers the host port and starts enumeration


  // Attach MIDI handlers
  midi1.setHandleNoteOn(handleNoteOn);
  midi1.setHandleNoteOff(handleNoteOff);
  midi1.setHandleControlChange(handleControlChange);
  midi1.setHandleProgramChange(handleProgramChange);
  midi1.setHandlePitchChange(handlePitchBend);
  midi1.setHandleAfterTouchPoly(handleAfterTouchPoly);
  midi1.setHandleAfterTouchChannel(handleAfterTouchChannel);
  midi1.setHandleSystemExclusive(handleSystemExclusive);


  Serial.println(F("[USB-MIDI] Ready. Connect a USB-MIDI keyboard to the host port."));
}


void loop() {
  myusb.Task();           // service the USB host controller
  while (midi1.read()) {  // dispatch all pending MIDI packets
    // Callbacks execute during read()
  }
}


// -------- MIDI callback implementations --------


void handleNoteOn(byte channel, byte note, byte velocity) {
  if (velocity == 0) {
    handleNoteOff(channel, note, 0);
    return;
  }
  digitalWrite(LED_BUILTIN, HIGH);
  Serial.print(F("Note On  ch="));
  Serial.print(channel);
  Serial.print(F(" note="));
  Serial.print(note);
  Serial.print(F(" vel="));
  Serial.println(velocity);
}


void handleNoteOff(byte channel, byte note, byte velocity) {
  digitalWrite(LED_BUILTIN, LOW);
  Serial.print(F("Note Off ch="));
  Serial.print(channel);
  Serial.print(F(" note="));
  Serial.print(note);
  Serial.print(F(" vel="));
  Serial.println(velocity);
}


void handleControlChange(byte channel, byte control, byte value) {
  Serial.print(F("CC       ch="));
  Serial.print(channel);
  Serial.print(F(" cc="));
  Serial.print(control);
  Serial.print(F(" val="));
  Serial.println(value);
}


void handleProgramChange(byte channel, byte program) {
  Serial.print(F("Program  ch="));
  Serial.print(channel);
  Serial.print(F(" program="));
  Serial.println(program);
}


void handlePitchBend(byte channel, int bend) {
  Serial.print(F("Pitch    ch="));
  Serial.print(channel);
  Serial.print(F(" value="));
  Serial.println(bend);
}


void handleAfterTouchPoly(byte channel, byte note, byte pressure) {
  Serial.print(F("PolyAT   ch="));
  Serial.print(channel);
  Serial.print(F(" note="));
  Serial.print(note);
  Serial.print(F(" pres="));
  Serial.println(pressure);
}


void handleAfterTouchChannel(byte channel, byte pressure) {
  Serial.print(F("ChanAT   ch="));
  Serial.print(channel);
  Serial.print(F(" pres="));
  Serial.println(pressure);
}


void handleSystemExclusive(const uint8_t *data, uint16_t length, bool lastChunk) {
  Serial.print(F("SysEx len="));
  Serial.print(length);
  Serial.print(lastChunk ? F(" (end) ") : F(" (cont) "));
  for (uint16_t i = 0; i < length; ++i) {
    if (data[i] < 16) Serial.print('0');
    Serial.print(data[i], HEX);
    if (i + 1 < length) Serial.print(' ');
  }
  Serial.println();
}

I programmed the code using platformio to my teensy and here is the platformio.ini
Code:
; PlatformIO Project Configuration File
;
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html


[env:teensy41]
platform = teensy
board = teensy41
framework = arduino
upload_protocol = teensy-cli
lib_deps =
    paulstoffregen/XPT2046_Touchscreen@0.0.0-alpha+sha.26b691b2c8
    lvgl/lvgl@^9.0.0
    bodmer/TFT_eSPI@^2.5.43
build_flags =
    -Ilib
    -D LV_CONF_INCLUDE_SIMPLE
    -D LV_CONF_SKIP
    -D LV_USE_TFT_ESPI
    -D TFT_CS=3
    -D USER_SETUP_LOADED
    -D ILI9341_DRIVER
    -D TFT_MISO=12
    -D TFT_MOSI=11
    -D TFT_SCLK=13
    -D TFT_CS=3
    -D TFT_DC=2
    -D TFT_RST=-1
    -D TOUCH_CS=5
    -D USB_MIDI_SERIAL


I can successfully run and upload the code but it seems it does not recognize the usb midi keyboard. the light on midi keyboard is off and when I check the output it is waiting for keyboard.
Could you help me to know how should I fix it? I am also not sure if I need to include Arduino. Because in other project in same hardware I am not improting Arduino
 
No light on the keyboard usually means no power on the USB Host port which means the myusb.begin(); has not been executed or there is a wiring issue on the USB Host port

I just ran your code in the IDE and plugged in a MIDI keyboard and it powers up and initializes OK and I get serial commands with key presses. Any chance you have the USBHost port cable inserted backwards on the Teensy? The power pin is the one closest to the USB connector.

BTW, you don't need the #include <Arduino.h>
 
Back
Top