PC USB to Arduino Serial MIDI

Whenever I’ve needed to get a computer to drive my MIDI setup I’ve wheeled out my Roland UM-ONE PC USB MIDI interface which gives my laptop a MIDI IN and OUT DIN plug.  But if I want to get my PC to drive the Arduinos I need to then plug the UM-ONE into one of the Arduino MIDI Interfaces to get it back to “Arduino serial port” signals. But some Arduino’s can talk USB, so why not try to plug the Arduino’s USB into the PC directly?

Now you can use things like the Hairless “Serial to MIDI bridge” to fool your computer into thinking the standard Arduino programming link is a MIDI port, but you can’t talk the MIDI baud rate of 31250.  This means that you have to have special “test code” in your Arduino to use the serial port at a standard PC rate rather than the MIDI rate – and I really didn’t want to change my Arduino code just for testing.

This project is the result of looking into that question.

  • In Part 2 I build this onto a shield.

These are some other possible posts of interest in this area too:

Warning! I strongly recommend using an old or second hand keyboard for your MIDI experiments.  I am not responsible for any damage to expensive instruments!

These are the key Arduino tutorials for the main concepts used in this project:

If you are new to Arduino, see the Getting Started pages.

Parts list

  • Arduino “Leonardo” compatible board (I used a “USB Beetle” board)
  • An existing Arduino MIDI project for testing

The Circuit

Most Arduino’s have a USB link, but it isn’t always available for your own projects as it is often provided by a different chip to the main processor.  It is normally considered just a power or programming link.

The exceptions are those based around devices such as the ATmega32U4 (or similar).  Consequently there are a range of Arduino type boards that have a “native” USB port (such as the Arduino DUE, the Micro, 101, Zero and so on) that allow you to access the USB port in your own programs to allow it to act as a USB device directly.  In our case this means they can act as a USB MIDI device when plugged into a computer.

I am using an Arduino Leonardo compatible board, called a “Beetle USB”, which is based on the ATmega32U4 and has the USB connector built-in to the circuit board.  This means that one end can be plugged directly in a PC and the serial lines can be connected directly to another Arduino as shown below.

PC USB MIDI Interface

The Code

We want the computer to be able to talk “MIDI” at the USB end and for it to appear as “Serial port MIDI” at the Arduino end.

Leonardo compatible boards have a native USB port, accessed from software using the “Serial” interface, as well as a UART serial port accessed from software using the “Serial1” interface.  This makes it relatively straightforward to link up Serial to Serial1 using software and pass messages between the USB and UART links.

This type of configuration is directly supported by the Arduino MIDI Library via the use of “transports” – these are the sections of code that link the MIDI processing in the library to a piece of actual hardware.  Up to this point we’ve just used the default “transport” which is the built-in serial port.  But now we want to enable a USB MIDI transport too.  The library also supports MIDI over Bluetooth “Low Energy” (BTLE) among others if you wanted wireless MIDI…

The following Arduino libraries are required (all installed in the usual way using the Arduino Library Manager):

  • The Arduino MIDI Library – “MIDI Library” by Francois Bests
  • The MIDI USB Transport – “MIDIUSB” by Gary Grewal
  • Arduino USBMIDI support – “USB MIDI Library for Arduino” by Blokas

The MIDI Library uses the MIDI USB transport which itself uses the baseline Arduino USBMIDI support.  Once you have all this, and you’ve configured your Arduino environment for an Arduino Leonardo board, then you are ready to go.

There is an example provided with the MIDI USB transport that seemed to do exactly what I wanted – it links USB MIDI to the serial port MIDI: Examples -> USB-MIDI -> MIDI_DIN2USB.ino

I’m pretty sure it worked once… but then I just couldn’t get it working again and couldn’t work out why.  I was seeing serial data coming out of the Beetle, but it wasn’t being recognised at the Arduino end. I don’t know if it was a baud issue or something else.

In the end I gave up trying to understand the example, which seemed to be passing on messages in both directions, and went for a simpler “single direction” solution.  This followed the principle I used in the Arduino MIDI Filter but initialises two instances of the MIDI library:

USBMIDI_CREATE_INSTANCE(0, MIDI_USB);
MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI_S);

And then polls the USB MIDI side and on receipt of any messages passes them over to the Serial side to send them out.

void loop()
{
  if (MIDI_USB.read()) {
    MIDI_S.send(MIDI_USB.getType(), MIDI_USB.getData1(), MIDI_USB.getData2(), MIDI_USB.getChannel());
  }
}

This seemed  lot more reliable for me.

Find it on GitHub Here.

To test it you will need something on your PC that can “talk MIDI” and select the “Arduino Leonardo” as your MIDI output device.  I use “MIDI Ox” as a MIDI tester which also comes with “MIDI Bar” which can play MIDI files to a device.  See: http://www.midiox.com/.

Closing Thoughts

I’m going to solder on a permanent lead to the Leonardo “Beetle” so I have a “plug into the PC and connect directly to the Arduino” MIDI interface which will make testing some of the visualisations a lot easier.

It is actually possible to reprogram the USB interface on an Arduino Uno (one example can be found here) – for official boards it is actually another ATmega device – so that leaves the possibility of having an Arduino Uno “talking MIDI” directly.  But this also means you can no longer program your Arduino using the normal methods so whilst it is an interesting technical experiment that I might look at, at some point, I think having a separate device as described above in this project will be a lot more use.

Kevin

Leave a comment