A simple bidirectional bridge between a class-compliant USB-MIDI device (e.g., Akai MPK mini MK3) and a 5-pin DIN MIDI interface.
Built with PlatformIO, using:
- USB Host Shield Library 2.0 (
felis/USB-Host-Shield-20) - Arduino MIDI Library (
FortySevenEffects/MIDI Library)
USB messages are forwarded to DIN OUT; DIN IN messages are forwarded to the attached USB-MIDI device.
- MCU: Arduino UNO (ATmega328P)
- USB Host Shield: MAX3421E-based (standard Arduino shield form factor)
- MIDI Shield: DIN IN/OUT/THRU + RUN/PGM switch
UNO (bottom)
└─ USB Host Shield (MAX3421E)
└─ MIDI Shield (DIN IN/OUT/THRU, RUN/PGM)
- USB Host Shield: SPI via ICSP header, SS = D10
- MIDI Shield:
- DIN IN → UNO D0 (RX)
- DIN OUT → UNO D1 (TX)
- RUN/PGM switch present on shield (see notes below)
- Power: 5 V & GND from the UNO
(Ensure the Host Shield’s VBUS (5 V) jumper is set correctly so it can power a bus-powered USB device.)
- Bridges common channel voice messages:
- Note On/Off, Control Change, Program Change, Pitch Bend, Aftertouch (poly & channel)
- Two-way: USB → DIN and DIN → USB
- Minimal and fast—no additional buffering threads
Not included (yet): SysEx & system real-time/common forwarding (easy to add later).
usb-midi-bridge/
├─ platformio.ini
└─ src/
└─ main.cpp
- PlatformIO (VS Code extension or CLI)
- Libraries (fetched automatically via
lib_deps):felis/USB-Host-Shield-20FortySevenEffects/MIDI Library @ ^5.0.2
- Clone this project into your PlatformIO workspace.
- Insert libraries: PlatformIO will auto-install from
platformio.ini. - Upload:
- On the MIDI Shield, set RUN/PGM to PGM while uploading (prevents Serial port conflicts).
- After upload completes, flip it back to RUN.
- Connect:
- Plug your USB-MIDI controller (e.g., MPK mini MK3) into the Host Shield’s USB-A.
- Connect DIN OUT to your synth’s MIDI IN, and/or feed DIN IN from an external source.
[env:uno]
platform = atmelavr
board = uno
framework = arduino
lib_deps =
felis/USB-Host-Shield-20
FortySevenEffects/MIDI Library @ ^5.0.2
; Note: The UNO’s hardware Serial (D0/D1) is used for DIN MIDI at 31250 baud.
; To avoid serial conflicts during upload, set the MIDI Shield’s RUN/PGM switch
; to PGM while uploading; switch it back to RUN after the upload completes.- Uses USBH_MIDI to receive/send USB-MIDI packets.
- Uses Arduino MIDI Library on
Serial(D0/D1) at 31250 baud. - Forwards:
- USB → DIN: Reads up to 3-byte channel messages and writes them to
Serial. - DIN → USB: MIDI callbacks translate events into USB packets.
- USB → DIN: Reads up to 3-byte channel messages and writes them to
- USB → DIN:
MidiHost.RecvData(m)fetches incoming USB-MIDI bytes; the sketch writes them to UART at 31250 baud (DIN). - DIN → USB: The MIDI library invokes handlers (e.g.,
handleNoteOn), which re-encode status/data bytes and callMidiHost.SendData(...).
- Power up the stack; plug in the USB-MIDI keyboard.
- Press keys—your synth connected to DIN OUT should play.
- (Optional) Send DIN IN messages from another source; they should appear on the USB device.
If nothing happens:
- Confirm the USB device is class-compliant MIDI (no vendor drivers required).
- Provide sufficient power (bus-powered controllers can draw ~100–500 mA).
- Re-seat shields; check the Host Shield’s LEDs (enumeration).
- Double-check the RUN/PGM switch state (RUN during operation).
-
UnknownPackageError / library not found
Use the exact slugs:felis/USB-Host-Shield-20FortySevenEffects/MIDI LibraryOr temporarily reference GitHub:
lib_deps = https://github.com/felis/USB_Host_Shield_2.0 FortySevenEffects/MIDI Library -
Upload fails / Serial busy
Set MIDI Shield RUN/PGM → PGM while uploading. -
No sound / device not detected
- Verify the Host Shield enumerates the device (power & cable).
- Confirm DIN cabling direction (OUT → IN).
- SysEx bridge: Use
USBH_MIDI::SendSysEx(...)and handle larger payloads fromRecvData(...). - System real-time: Forward timing/clock/Start/Stop messages.
- Debug UART: Add
AltSoftSerial(on different pins) at 115200 for logging sinceSerialis reserved for 31250 baud MIDI. - RUN/PGM input: Wire the switch to a digital pin to auto-mute DIN during uploads.
This project is licensed under GPL-2.0.
See the included LICENSE file for the full text.
This project links against USB Host Shield Library 2.0, which is GPL-licensed. Therefore, the combined work must be distributed under a GPL-compatible license. The Arduino MIDI Library is MIT-licensed and is compatible with GPL.
- USB Host Shield Library 2.0 — GPL-2.0
- Arduino MIDI Library (FortySevenEffects) — MIT
- USB Host Shield Library 2.0 by Oleg Mazurov & contributors
- MIDI Library by FortySevenEffects & contributors