Adafruit_TinyUSB_Arduino: USB MIDI device name not being changed

Operating System

Windows 10

IDE version

Arduino 1.8.19

Board

Wemos ESP32-S2 Mini

ArduinoCore version

Espressif Systems Version 2.0.3

TinyUSB Library version

Version 1.14.3

Sketch (attached txt file)

#include <Arduino.h>
#include <Adafruit_TinyUSB.h>
#include <MIDI.h>

// USB MIDI object
Adafruit_USBD_MIDI usb_midi;

// Create a new instance of the Arduino MIDI Library,
// and attach usb_midi as the transport.
MIDI_CREATE_INSTANCE(Adafruit_USBD_MIDI, usb_midi, MIDI);

// Variable that holds the current position in the sequence.
uint32_t position = 0;

// Store example melody as an array of note values
byte note_sequence[] = {
  74,78,81,86,90,93,98,102,57,61,66,69,73,78,81,85,88,92,97,100,97,92,88,85,81,78,
  74,69,66,62,57,62,66,69,74,78,81,86,90,93,97,102,97,93,90,85,81,78,73,68,64,61,
  56,61,64,68,74,78,81,86,90,93,98,102
};

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);
  
//  usb_midi.setStringDescriptor("TinyUSB MIDI");
  TinyUSBDevice.setProductDescriptor("TinyUSB MIDI");

  // Initialize MIDI, and listen to all MIDI channels
  // This will also call usb_midi's begin()
  MIDI.begin(MIDI_CHANNEL_OMNI);

  // Attach the handleNoteOn function to the MIDI Library. It will
  // be called whenever the Bluefruit receives MIDI Note On messages.
  MIDI.setHandleNoteOn(handleNoteOn);

  // Do the same for MIDI Note Off messages.
  MIDI.setHandleNoteOff(handleNoteOff);

  Serial.begin(115200);

  // wait until device mounted
  while( !TinyUSBDevice.mounted() ) delay(1);
}

What happened ?

The line:

TinyUSBDevice.setProductDescriptor("TinyUSB MIDI");

should apparently change the USB device’s product name, but it doesn’t. The Midi device is still detected as “LOLIN-S2-MINI”

Also the line: usb_midi.setStringDescriptor("TinyUSB MIDI"); doesn’t seem to do anything.

How to reproduce ?

Flash the code to the ESP32-S2 Mini board, connect it to the computer’s USB port, open the MIDI Monitor software, and check the MIDI device In/Out ports name. It should have changed to what I set in the code, but it doesn’t.

There seems to be very little information about how to use this library on the internet, specially with midi. Perhaps I am doing something wrong as I am a beginner, but this looks like a bug to me. As I said, there is very little information on this subject. Or at least I cannot find it.

Debug Log

No response

Screenshots

No response

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 17 (5 by maintainers)

Most upvoted comments

these values are being pulled in from .platformio/packages/framework-arduinoespressif32/variants/lolin_s2_mini/pins_arduino.h

#define USB_MANUFACTURER 	"WEMOS.CC"
#define USB_PRODUCT 		"LOLIN-S2-MINI"

There seems to be some disconnect between this library layer and whatever the espressif32 framework is doing to set up the device descriptors. It would be nice to correctly manipulate the descriptors from this side.

There’s a comment and ifdef in this libary which stubs out the descriptor handling in Adafruit TinyUSB Library/src/arduino/Adafruit_USBD_Device.cpp

// EPS32 use built-in core descriptor builder.
// Therefore most of descriptors are stubs only
#ifdef ARDUINO_ARCH_ESP32

therefore it seems that this library does not attempt at all to set up any descriptors on ESP32, and uses the framework defaults.

If I change this ifdef so that the else clause is compiled, then setting the strings from my application code works as expected

#ifdef DISABLED_ARDUINO_ARCH_ESP32

I only had to comment out one other line (329)

  // SerialTinyUSB.begin(115200);

Minimal example which works with the above modifications

#include <Arduino.h>
#include <Adafruit_TinyUSB.h>

Adafruit_USBD_MIDI usb_midi(1);

void setup()
{
  Serial.begin(115200);

  TinyUSBDevice.clearConfiguration();
  TinyUSBDevice.setManufacturerDescriptor("Your Name");
  TinyUSBDevice.setProductDescriptor("Your Thing");
  TinyUSBDevice.setSerialDescriptor("Your Thing CDC");

  usb_midi.setCableName(1, "Your Thing Port");

  usb_midi.begin();
}

void loop()
{
  delay(1000);
  Serial.printf(".");
}

Caveat though that in this setup there is no usb serial console … so no debug interface and you have to manually put the device into flash boot mode to update the firmware.

There is an on going PR that rework how descriptors is built/integrated with arduino-esp32 core, which allow dynamic descriptors for esp32. You can try it out https://github.com/adafruit/Adafruit_TinyUSB_Arduino/pull/372, let me know if that works for you. If everything go well we can release it as v3

And to make the USB Serial work again, you can construct your own basic class for this

class MyUSBCDC : public Adafruit_USBD_CDC, public Adafruit_USBD_Interface
{
public:
  MyUSBCDC(uint8_t itf = 0) : Adafruit_USBD_CDC(itf)
  {
  }

  virtual uint16_t getInterfaceDescriptor(uint8_t itfnum, uint8_t *buf,
                                          uint16_t bufsize)
  {
    // EPOUT = 0x00;
    // EPIN = 0x80;

    // CDC is mostly always existed for DFU
    // usb core will automatically update endpoint number
    uint8_t desc[] = {TUD_CDC_DESCRIPTOR(itfnum, 0, 0x80, 8, 0x00, 0x80, 64)};
    uint16_t const len = sizeof(desc);

    if (bufsize < len)
    {
      return 0;
    }

    memcpy(buf, desc, len);
    return len;
  }
};

MyUSBCDC USBSerial(0);

void setup() {

  USBSerial.begin(115200);

  TinyUSBDevice.clearConfiguration();
  TinyUSBDevice.setManufacturerDescriptor("Your Name");
  TinyUSBDevice.setProductDescriptor("Your Thing");
  TinyUSBDevice.setSerialDescriptor("Your Thing CDC");
  TinyUSBDevice.addInterface(USBSerial);
}

Then use USBSerial in your app code instead of Serial. This also allows the upload to work again without manually entering DFU.