Pi Pico MIDI Button Voice Select

This is an alternative take on my Arduino MIDI Button Voice Select this time combining it with both my Pi Pico MIDI Button Controller with a hint of the CircuitPython USB to Serial MIDI Router too.  The end result is a voice and bank selector that will also act as a USB MIDI to serial MIDI converter.  In the case of the MiniDexed it means that this can be used to add USB MIDI device functionality to the MiniDexed (something it can’t do on its own – it can only act as a USB MIDI host).

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

  • Raspberry Pi Pico (or other CircuitPython compatible RP2040 device)
  • 5 banks of 8 buttons (see photos – I searched for “matrix 8 keypad” using online auction or Chinese marketplace sites)
  • Optional: For serial MIDI: a 3V3 compatible Ready-Made MIDI Modules
  • Breadboard and jumper wires
  • A synth module to control. Once again I’m using my MiniDexed.

The Circuit

PicoMIDIButtonVoiceSelect_bb

As I mentioned last time, these switches have a peculiar ordering to them:

  • Top Row: K7-K5-K3-K1
  • Bottom Row: K8-K6-K4-K2

The Pico’s TX and RX pins can be connected to an optional 3V3 compatible MIDI interface module to support 5-pin DIN serial MIDI as well as USB MIDI.  Note that the Pico will be acting as a USB MIDI Device (not a USB host).

Use with MiniDexed

To use this as a voice/bank selector and USB MIDI device interface for a MiniDexed, the following connections are required between the Pico and the Raspberry Pi:

  • RPi GPIO 15 (RXD) to Pi Pico GP0 (TX).
  • RPi GND to Pi Pico GND.
  • Pico USB to PC USB.
  • RPi power and audio.

Pi Pico to RPi MIDI

Key points:

  • No serial MIDI interfaces are required as both the Pico and the RPi can “talk” direct 3V3 logic level serial by connecting the RX/TX pins together in the required direction.
  • The RPi and Pico are powered independently, but if using the Pico as a USB MIDI device, the Pico will be powered over USB.  The GND links still need to be connected though to ensure a common base level for the serial communications.
  • The diagram shows the Pico being used as a USB MIDI device interface for the Raspberry Pi, but it can also act as a USB MIDI device /to/ the Raspberry Pi if required (in which case it can be powered from the Pi over USB too).
  • To run MiniDexed, other hardware is likely to be required on the Raspberry Pi (for details see: “Bare Metal” Raspberry Pi MiniDexed DX7).

IMG_6215

The Code

I’m programming this one in CircuitPython, so I’m using the same basic “keypad” style button decoding I used with my Toy Keyboard USB Matrix Decode with the Pi Pico but this time I’m turning button presses into MIDI Program Change and Control Change BANKSEL messages.

I’ve also combined it with the CircuitPython USB to Serial MIDI Router to provide the USB to serial MIDI functionality.

To map the buttons over to MIDI messages, I’ve again allocated the numbers 1 to 40 to the keys so that numbers 1 to 16 form a “top row”; 17 to 32 form a “bottom row”‘ and 33 to 40 are eight “bank selection” switches.

ArduinoMIDIButtonVoiceSelect

Due to the weird numbering of the keys, I have to provide a mapping between keypresses and the codes to be generated.  This takes place in two lists at the top of the code:

ccs = [
[0, 3], [0, 7], [0, 2], [0, 6], [0, 1], [0, 5], [0, 0], [0, 4]
]

pcs = [
3, 19, 2, 18, 1, 17, 0, 16,
7, 23, 6, 22, 5, 21, 4, 20,
11, 27, 10, 26, 9, 25, 8, 24,
15, 31, 14, 30, 13, 29, 12, 28
]

I could have done this more intelligently in the code, or could have fiddled about with the wiring, but opted to do it this way to keep things as transparent as possible if anything needs changing!

In terms of the routing function, as this is all in CircuitPython I’m using the Adafruit MIDI library, but as far as I can see, this will only allow you to receive and send MIDI messages it already knows about – I don’t believe it is possible to say “if we don’t understand this message, just send it on anyway”.

Assuming I’ve interpreted this correctly, this means that anything that comes up as “MIDIUnknownEvent” will be dropped, which isn’t ideal.

Find it on GitHub here.

Closing Thoughts

In the video I’m playing one of my Lo-Fi Orchestra MIDI files through the Pico into the MiniDexed and latency wise it all seems fine.  As it is playing you can see me changing voices and banks and it all seems to work.

I haven’t decided if the Arduino or Pico version works better yet.  I suspect the performance won’t be too dissimilar as whilst the Pico is more powerful, it is running an interpreted language rather than “raw C”.

But having options is always good and I suspect the CircuitPython version might be more “tweakable” to some.

Kevin

4 thoughts on “Pi Pico MIDI Button Voice Select

  1. I had trouble getting CircuitPython to properly receive MIDI – especially multiple channels – using the Adafruit MIDI library.
    Many messages are dropped if the MIDI has more than a few events being received in real-time, for example if the MIDI stream includes Clock messages. So I wrote code at a lower level – where all MIDI events are processed (or ignored on purpose). It still drops messages when multiple channels of chord notes are too quickly received, but it’s much better than the library. You may find this code useful, to deal with the MIDIUnknownEvent issue.
    https://github.com/gmeader/pybadge/blob/master/MIDImatrix/midimatrix.py

    Liked by 1 person

  2. Yes, thanks for that. I had to do something similar with Micropython as it has no MIDI support built in. I might port that over to CircuitPython too..

    Ultimately at some point I really should crack open the SDK for the Pico and so some C/C++ 🙂

    I loved that video – I remember seeing it at the time!

    Kevin

    Like

    1. The main thing that is stopping me, is not quite knowing what the USB equivalent of the MIDI byte stream is. I know how to get that from the uart but not from USB at present. I need to do some reading and playing 🙂

      Like

Leave a comment