MIDI, CircuitPython, CPX and Pi Pico

Inspired by my initial play with the Raspberry Pi Pico and MicroPython, I wanted to also see what I could do with both the Micro:bit and my Adafruit Circuit Playground Express MIDI-wise too.  Both are 3.3V boards and both can run a variant of MicroPython – either native or using the Adafruit version – CircuitPython.

This post documents how how to send MIDI using the Adafruit Circuit Playground Express and some pointers for doing the same on the Pi Pico.

2021-01-26 21.41.36

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:

Update Feb 2021: If you are after MIDI IN functionality, then see MIDI In for 3.3V Microcontrollers.

Update Jun 2021: It is now possible to use the serial MIDI functionality in CircuitPython on the Pico, see Toy Keyboard USB Matrix Decode with the Pi Pico – Part 2.

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

Parts list

  • Adafruit Circuit Playground Express
  • One of the Ready-Made MIDI Modules that supports 3.3V signals
  • 5-pin 180 DIN socket, 10Ω and 33Ω resistors
  • Breadboard and jumper wires

The Circuit

CPXMIDIOut_bb

This is exactly the same MIDI circuit as described for the Raspberry Pi Pico, and in theory it should also be the same for the BBC Micro:bit when I get that far.

In fact in the photo above you can see I just removed the jumper leads from my Raspberry Pi Pico and hooked them up to the CPX instead, allowing for quick changes between the two boards.

The Code

My initial aim was to get the same MIDI sending demo code running on my Raspberry Pi Pico but using CircuitPython instead.  There is already a version of CircuitPython for the Pi Pico and details of how to get it up and running can be found here: https://learn.adafruit.com/getting-started-with-raspberry-pi-pico-circuitpython.

Unfortunately there was an immediate problem.  When trying to run my “Bach” code from before, it just stopped completely.  Running a simple LED demo was fine, but the MIDI code – nothing worked.  It turned out there were a number of things going on here:

  • First of all, some of the libraries are different between the two systems.  For MicroPython there is a “machine” class, for CircuitPython there is a “board”… so even for my simple demo code, changes were needed straight away just to find the on-board LED.  Then other changes were needed to access the UART.
  • Then it would seem that CircuitPython does not like such large lists of numbers, whereas MicroPython didn’t seem to mind.  The technical explanation is due to the size of the “stack”, but the details don’t matter here.  The work around was to split up the list of notes into smaller chunks so that CircuitPython didn’t have to try to work on it all in one go.
  • Finally, it would appear that the UART support for the Raspberry Pi Pico is still a work in progress and isn’t ready yet.

So the summary of all this is that I now have some working MIDI sending code for the Circuit Playground Express, but while I believe it will eventually work on the Pi Pico, I need to sit tight on it for a bit longer until the UART support is ready.  Update: This is now supported, find details here.

Here is the latest test code.

import board
import time
import digitalio
import busio

led = digitalio.DigitalInOut(board.LED)
led.direction = digitalio.Direction.OUTPUT
uart = busio.UART(tx=board.TX, rx=board.RX, baudrate=31250)

notes = [60, 61, 62, 63, 64, 65, 64, 63, 62, 61]

def playNote(note):
led.value = True
uart.write(bytes([0x90, note, 127]))
time.sleep(0.150)
led.value = False
time.sleep(0.050)
uart.write(bytes([0x80, note, 0]))

while True:
for x in notes:
playNote(x)

It is turning out to be quite a learning curve for me, but then I’ve not really just got on and had a go with any variant of Python before now.

To have it running on the Pi, just needs the following line changing at the top:

uart = busio.UART(tx=board.GP4, rx=board.GP5, baudrate=31250)

In theory of course.  In practice I’ve yet to be able to try it.

Closing Thoughts

I really liked the idea of having one simple environment on a range of easy to use boards, but it would seem that so far there isn’t one version that is available on the CPX, Raspberry Pi Pico and the BBC Micro:bit, so I’m probably going to have to learn about both MicroPython and CircuitPython for the time being.

One advantage of getting CircuitPython going over MicroPython is that there is an Adafruit MIDI library all ready to go.  All of the examples seem to be tied into providing USB MIDI at the moment, but I’m hoping it will be a relatively straight forward task to switch to UART based MIDI for any of these boards.  I’ve not seen the same for MicroPython.

I’d also like to find a nice “off the shelf” solution for a two-way MIDI interface for each of them too, even if that means building my own “off the shelf” simple shield.

I also want to get on to some of the more audio related demonstrations and again it looks like there may be more libraries within CircuitPython for other audio functions too.

Kevin

Leave a comment