Pico Unicorn MIDI Visualiser

I’ve been waiting to use my Pimoroni Unicorn Pack for the Raspberry Pi Pico for some time, so decided to start off with a remake of my TFT MIDI Display – Part 3.

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 Arduino tutorials for the main concepts used in this project:

Note that I’ve classified this as “beginner” if you can use a ready-made MIDI module, but if you are building or wiring up one yourself, it is an intermediate project.

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

Parts list

The Circuit

IMG_5610

This uses a Raspberry Pi Pico plugged into a Pimoroni Unicorn pack but with a MIDI interface connected to one of the hardware serial ports (UARTs) on the Pico.  The best way to do this is to use some kind of IO expander to gain access to the IO pins while the Unicorn Pack is plugged in and to then use a ready made or DIY MIDI interface suitable for use with 3.3V microcontrollers.

Here I’m using my Raspberry Pi Pico MIDI ‘pack’ Interface and a Pimoroni Quad Expander.

The Code

In order to use the Unicorn Pack you have to install the Pimoroni version of Micropython which includes all the “driver” support for their products.  Full details of how to do this can be found here:

The code makes use of my SimpleMIDIDecoder (details here) which makes acting on MIDI notes relatively straight forward.  I’ve also include a “thru” function to allow notes to be played through the visualiser on to a sound module of some sort.

I’ve mapped MIDI notes onto pixels on the Unicorn display on an octave per row basis. This means there are four unused pixels on each row.  To work out the (x,y) coordinates that corresponds to a MIDI note, I’ve included a midi2pixel routine:

def midi2pixel(note):
    y = (int)(note/MIDI_W)
    x = note-y*MIDI_W
    y = y + MIDI_HS
    x = x + MIDI_WS
    y = MIDI_H - 1 - y
    return x, y

This allows me to provide an offset on the rows, and to specify which MIDI notes map onto rows of the display using the MIDI_WS and MIDI_HS values (“width start” and “height start”).  This also reverse the y-coordinate to get the orientation I want, with the lowest notes at the bottom of the display.

I’ve also included some functions to map notes onto different colours, using the hsv_to_rgb function that was used in the Pimoroni example code.  This is optional, but gives a nice colour gradient across the display as the different notes light up.

I’ve also included a “test pattern” that is shown on power-up to show that the display is working and to highlight the extremes of the range of notes recognised.  You can see the test pattern in the above photo.

Find it on GitHub here as PicoUnicornMIDIVisualiser.py and SimpleMIDIDecoder.py.

Closing Thoughts

This was simply the first idea for the Unicorn Pack.  Other ideas might be some kind of “waterfall” display; or having colours represent different notes or different velocities or different channels.

It would also be nice to create a version that supports USB MIDI too.

In the video you can see it having my Lo-Fi Orchestra – Sky Toccata played through it on to my MT-32 synth module.  Note that only a few channels are sounding – this is not the full MIDI in action – but it shows how the visualiser works.

Kevin

Leave a comment