Pi Pico PIO Poly Tone MIDI Keyboard

Following on from the Pi Pico PIO Poly Tone Keyboard here it is combined with one of the DIY MIDI Interfaces to give an eight note polyphonic MIDI tone module based on the Raspberry Pi Pico.

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:

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

Parts list

The Circuit

PiPicoPolyToneMIDI_bb

This is simply the MIDI interface from MIDI In for 3.3V Microcontrollers and the output mixer section of the Pi Pico PIO Poly Tone Keyboard.  In my video I’ve also kept the button keyboard and the code actually will support both the independent keyboard and MIDI input at the same time.

Allowing for the additional IO to drive the keyboard means that this time I’m using UART 0 for the MIDI link.  The MIDI circuit is thus wired into GP1 which is the UART 0 RX pin.

2021-02-19 21.07.31

The Code

This is primarily a merge between the code from the two projects.  As already mentioned the UART has to be initialised to use UART 0.

uart = machine.UART(0,31250)

And the MIDI note On and Off routines from the previous project now simply call the new noteOn and noteOff routines to enable the tones.

# Basic MIDI handling commands
def doMidiNoteOn(note,vel):
if (vel == 0):
noteOff(note)
return

pin.value(1)
noteOn(note)

def doMidiNoteOff(note,vel):
pin.value(0)
noteOff(note)

The only other thing to add, other than the MIDI handling code itself (which is a straight copy from before) is a call to check the serial port as part of the main loop.  As the main loop checks each column for the keyboard handling in turn, I opted to check for MIDI messages within this loop to ensure a good MIDI response.

while True:
for c in range(0, numcols):
# Column handling ...

for r in range(0, numrows):
# Row handling ...

# Now check for MIDI messages too
if (uart.any()):
doMidi(uart.read(1)[0])

You can hear it working in the video.  Note how pressing the same key over MIDI as is being played on the keyboard (or vice versa) means that the original note gets cut off on key release.  It doesn’t “stack up” the key presses if a note is played twice.

In fact, I haven’t checked it but there is nothing in the code that looks to see if the note is already playing so it is entirely possible that a second oscillator will start up playing the same note!  But when I send of the noteOff events, I look for all instances of the note playing, not just the first, so that will tidy things up there.  In principle I guess if I only handle the first “note Off” then it would yield a more expected note off response when used with two keyboards.  But I like the option to “mop up” any potentially stuck notes, so I’ll leave it as it is.

There is one constraint still in there – the code only goes down to C3.  It is probably extendable, but I don’t know at what point the frequency handling starts to break down… I’ll explore the limits, both high and low, at some point, but not right now.

Find it on GitHub here.

Closing Thoughts

As mentioned in my last post, it is now probably time to explore other sound generating options with the Pico, such as using the PIO for PWM output for some direct digital synthesis and my Pimoroni Audio Pack.

I’ve also seen many people now using the Pico as a USB MIDI controller, but I’m now wondering if I can make it a USB MIDI host – then I could plug my Korg miniKeys into it directly… in this video, I used my Mini USB-MIDI to MIDI converter.

Kevin

Leave a comment