PC USB-MIDI to MIDI Revisited

This is another take on the PC USB to Arduino Serial MIDI once again taking the Pro Micro I used in part 2.

Recall that the Pro Micro board (not to be confused with the Arduino Micro or the Pro Mini) is an Arduino Leonardo compatible smaller board, using the ATmega32U4, which means it has a built-in USB interface.

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

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

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

Parts list

The Circuit

USBMIDI-ProMicro_bb

The circuit is fairly straight forward.  The USB MIDI link is using the on-board micro-USB connector and the serial port (UART) using the RX/TX pins are connected to one of the ready-made MIDI interfaces along with power and ground.  Note that I’m using the VCC power pin, not “RAW”.

Note that the Pro Micro comes in two flavours – a 5V/16MHz version and a 3.3V/8MHz version.  This is using the 5V/16MHz version.  It might be possible to use the other one, but you’ll need a 3.3V compatible MIDI interface if you do and I’m not sure what the performance would be like.

The Code

The USB-MIDI library provides the required USB MIDI support for the standard Arduino MIDI library.  This has to be installed alongside the MIDIUSB library too.

In principle, everything we need to do this is in the MIDI_DIN2USB example provided with the USB-MIDI library, but it just doesn’t work for me.  I don’t know why, but I know a little more than I did last time.

So, I have to use code like the following in the callback for receiving a message.

midiCallbackFunction (MIDI message):
  SWITCH (type of MIDI message):
    NoteOn: pass to other interface sendNoteOn function
    NoteOff: pass to other interface sendNoteOff function
    ... and so on for each required MIDI message type...

We need to remember to disable MIDI THRU for the serial port.  This is the only MIDI library transport where the “software thru” functionality is enabled automatically.

In my own code, I’ve also simplified the MIDI initialisation “magic” code compared to the provided example.

#include <MIDI.h>
#include <USB-MIDI.h>

USING_NAMESPACE_MIDI;
USBMIDI_CREATE_INSTANCE(0, MIDI_USB);
MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI_S);
typedef Message<MIDI_NAMESPACE::DefaultSettings::SysExMaxSize> MidiMessage;

The last line (creating a MidiMessage type as shown)  is required to use the “more internal” handleMessage callback.  This takes an “internal” MidiMessage and in principle should be able to pass it straight on to the transport’s send() function, which has the following comment in the MIDI library:

“Typically this function is use by MIDI Bridges taking MIDI messages and passing them thru.”

Which of course is exactly what we want to be doing here.  Unfortunately as stated above, this doesn’t work this simply for me.  When using transport.send(message) I seem to only get zeros sent out over MIDI. I have no idea why.  Splitting out the parameters from the message structure and calling the more specific send() functions works fine.  I’ve started a discussion in the USB-MIDI library to see if anyone has any idea why as I’ve run out of things to try (and C++ templates and references are really not my strong point!).

Find it on GitHub here.

Closing Thoughts

The ATmega32U4 based boards are actually pretty interesting and I’ve still not really done very much with them.  As well as USB support, they have more analog ports and the ability to use serial USB at the same time as the UART serial port would make debugging many of my MIDI using projects a lot easier.

They also include an extra hardware timer, but programming it is a bit different to other timers, but it doesn’t include “Timer 2” which means that a fair bit of code using Arduino ATmega328 timers directly would need looking at.

I’d like to get to the bottom of the problem with using the “send” function, as otherwise this is a great two-way MIDI to USB interface.

I don’t believe you can have USB host functionality so that would rule out having any kind of USB-MIDI to DIN MIDI converter, but as a PC USB MIDI interface it seems to work fine.

Kevin

Leave a comment