Midi2piousbhub
Use a Raspberry Pi Pico/RP2040 to connect a MIDI USB Host, a serial port MIDI, Bluetooth MIDI and 0-4 USB MIDI devices on a USB hub
Install / Use
/learn @rppicomidi/Midi2piousbhubREADME
midi2piousbhub
Use a Raspberry Pi Pico to interconnect a MIDI host, a serial MIDI device and up to 4 MIDI devices via a USB hub. If you have a Pico W or compatible board, this project supports connection from a Bluetooth MIDI client (iPad, phone, PC...) or connection to a Bluetooth MIDI server (Bluetooth MIDI Keyboard, control surface, etc.)
This project uses the RP2040 processor's built-in USB port as a USB device port for connection to a USB MIDI host like a PC or Mac. It uses the RP2040's PIO 0 plus 2 GPIO pins to create a USB host port, and it uses the RP2040 processor's built-in UART1 port for serial port MIDI. Bluetooth MIDI uses the Pico W's built-in WiFi/Bluetooth module.
You configure how the MIDI streams connect by using serial terminal command line interface (CLI) connected to either the RP2040's UART0 port or the RP2040's built-in USB port's serial (CDC ACM) interface.
The software uses some of the Pico board's program flash for a file system to store configurations in presets. If you save your settings to a preset, then the midi2piousbhub software will automatically reload the last saved preset on startup and when you plug a USB MIDI Device to the host port. You can back up any or all of your presets to a USB Flash drive connected to the USB hub. Presets are stored in JSON format.
KNOWN ISSUE: At the time of this writing, MIDI device unplug from a USB hub is not detected and will confuse the software.
WORKAROUND: Unplug the USB Hub first. Unplug the USB MIDI device second. Finally, plug the hub back in. The remaining devices should reconnect.
Hardware
My first test circuit used a Raspberry Pi Pico board, a USB A breakout board, and a hand wired MIDI I/O port. The circuit is the same as the hardware described in the usb_midi_host README "Software-based USB Host Port: Pico_PIO_USB Library" section except I wired a MIDI IN and MIDI OUT port to pins GP4 and GP5 like the midi2usbhost project shows.
However, it should also run on the Adafruit Feather RP2040 with USB Type A Host with pins D4 and D5 wired to an Adafruit MIDI FeatherWing board (take FeatherWing 3.3V power and ground from the RP2040 board), or any similar hardware configuration.
Setting Up Your Build and Debug Environment
I am running Ubuntu Linux 24.04LTS on an old PC. I have Visual Studio Code (VS Code) installed and went through the tutorial in Chapter 7 or Getting started with Raspberry Pi Pico to make sure it was working first. I use a picoprobe for debugging, so I have openocd running in a terminal window. I use minicom for the serial port terminal (make sure your linux account is in the dialup group). I found that when debugging using the picoprobe whilst also using the Pico board as a USB device connected to the same PC, I had to connect the picoprobe first, then connect the target Pico board via a USB hub. Your experience may be different.
You do not need to use the picoprobe or the UART 0 output at all. The USB device connector on the RP2040 target board serves both as a MIDI port and serial port console.
Install the Pico C/C++ SDK
If you have not already done so, follow the instructions for installing the Raspberry Pi Pico SDK in Chapter 2 of the
Getting started with Raspberry Pi Pico
document. In particular, make sure PICO_SDK_PATH is set to the directory where you installed the pico-sdk.
Pico W Users: Update the Pico SDK
At the time of this writing, the Pico C/C++ SDK version is 2.1.1. It has fixed some of the issues with the Bluetooth that were present in earlier versions. Please use that version or later.
Use a TinyUSB library version that supports native USB MIDI Host
Until recently, TinyUSB did not support USB MIDI Host with its own driver. Recently, that changed. Please update to the latest TinyUSB version (May 6, 2025, commit 542e5b4550a01d034b78308d77c408ed89427513, at the time of this writing in case the latest version does not build).
- Set the working directory to the tinyusb library and make sure you are on the main branch.
cd ${PICO_SDK_PATH}/lib/tinyusb
git checkout master
- Check the date on the last commit to the TinyUSB library master branch.
git log -1
- If the version is new enough, do nothing. Otherwise,
git pull
Install PIO USB support for TinyUSB
The latest TinyUSB does not come with PIO USB driver source code. To install that source, you need to have Python 3 installed on your computer. From a command line, type
cd ${PICO_SDK_PATH}/lib/tinyusb
python tools/get_deps.py rp2040
For more information, see the TinyUSB documentation
Note that on some OS installations, you have to type python3 instead of python to invoke the python 3
interpreter. It depends on your installation.
At the time of this writing, this will install Pico PIO USB commit 810653f66adadba3e0e4b4b56d5167ac4f7fdbf7 from March 25, 2025. This version of code has the MIDI device unplug detect issue as noted above. Subsequent versions seem to introduce other issues in my testing. This could change (hopefully for the better) as Pico-PIO-USB and TinyUSB development progresses.
Get the project code
Clone the midi2piousbhub project to a directory at the same level as the pico-sdk directory.
cd ${PICO_SDK_PATH}/..
git clone --recurse-submodules https://github.com/rppicomidi/midi2piousbhub.git
Command Line Build (skip if you want to use Visual Studio Code)
Enter this series of commands (assumes you installed the pico-sdk and the midid2usbhub project in the ${PICO_MIDI_PROJECTS} directory)
If your system is based on a Pico W board, enter this command first
export PICO_BOARD=pico_w
If your system is based on a Adafruit Feather RP2040 with USB A Host, enter this command first
export PICO_BOARD=adafruit_feather_rp2040_usb_host
If your system is based on a Pico board, enter this command first
export PICO_BOARD=pico
Other RP2040 and RP2350 boards have not been tested. Substitute
your board after the PICO_BOARD= if your board is not listed.
Next, enter these commands.
export PICO_SDK_PATH=${PICO_MIDI_PROJECTS}/pico-sdk/
cd ${PICO_MIDI_PROJECTS}/midi2piousbhub
mkdir build
cd build
cmake ..
make
The build should complete with no errors. The build output is in the build directory you created in the steps above.
Troubleshooting
If your project works for some USB MIDI devices and not others, one
thing to check is the size of buffer to hold USB descriptors and other
data used for USB enumeration. Look in the file tusb_config.h for
#define CFG_TUH_ENUMERATION_BUFSIZE 512
Very complex MIDI devices or USB Audio+MIDI devices like DSP guitar pedals or MIDI workstation keyboards may have large USB configuration descriptors. This project assumes 512 bytes is enough, but it may not be for your device.
To check if the descriptor size is the issue, use your development computer to dump the USB descriptor for your device and then add up the wTotalLength field values for each configuration in the descriptor.
For Linux and MacOS Homebrew, the command is lsusb -d [vid]:[pid] -v For Windows, it is simplest to install a program like Thesycon USB Descriptor Dumper.
For example, this is the important information from lsusb -d 0944:0117 -v
from a Korg nanoKONTROL2:
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x0053
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 100mA
This is the important information from the Thesycon USB Descriptor Dumper for a Valeton NUX MG-400
0x01 bNumConfigurations
Device Qualifier Descriptor is not available. Error code: 0x0000001F
-------------------------
Configuration Descriptor:
-------------------------
0x09 bLength
0x02 bDescriptorType
0x0158 wTotalLength (344 bytes)
0x04 bNumInterfaces
0x01 bConfigurationValue
0x00 iConfiguration
0xC0 bmAttributes (Self-powered Device)
0x00 bMaxPower (0 mA)
You can see that if CFG_TUH_ENUMERATION_BUFSIZE were 256 instead of 512,
the Korg nanoKONTROL2 would have no trouble enumerating but the Valeton
NUX MG-400 would fail because TinyUSB couldn't load the whole configuration
descriptor to memory.
Terms this document uses
- Connected MIDI Device: a MIDI device connected to a USB hub port or to a serial port MIDI DIN connector, or the USB C Device interface or the Bluetooth LE MIDI.
- USB ID: A pair of numbers the Connected MIDI Device reports to the hub when it connects. They are supposed to be unique to a particular product. The MIDI DIN connectors, the USB C Device interface, and the Bluetooth LE MIDI interface have fake USB ID numbers to be compatible with this system.
- Routing Matrix: The software that sends MIDI data to and from Connected MIDI Devices
- Terminal: a MIDI data input to or output from the Routing Matrix.
- FROM terminal: an input to the Routing Matrix. It will be a MIDI OUT signal from a Connected MIDI Device.
- TO terminal: an output from the Routing Matrix. It will be a MIDI IN signal to a Connected MIDI Device.
- Port: usually a group of 1 MIDI IN data stream and one MIDI OUT data stream associated with a Connected MIDI Device. A Port of a Connected MIDI Device may omit MIDI IN or MIDI OUT, but not both. Ports are numbered 1-16
- Direction of a te
Related Skills
node-connect
348.5kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
109.1kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
348.5kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
348.5kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
