In the next part of my messing around with the Raspberry Pi Pico PIO polyphonic tones, I’ve paired it up with my Pi Pico Keypad MIDI Step Sequencer using my Pimoroni RGB Keypad.
- In part 2 I add some MIDI controllers.
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:
- MIDI, MicroPython and the Raspberry Pi Pico
- Pimoroni RGB Keypad Base Tutorial
- Raspberry Pi Pico’s PIO for mere mortals – Part 3 – Sound
- Pi Pico PIO Poly Tone MIDI Keyboard
- Pi Pico PIO Poly Tone MIDI “Pack”
If you are new to microcontrollers, see the Getting Started pages.
- Raspberry Pi Pico
- Pimoroni RGB Keypad Base
- Pimoroni Pico Omnibus Dual Expander (optional)
- Pi Pico PIO Poly Tone MIDI “Pack” or solderless breadboard equivalent
- Amplification as required
Once again I am using the MicroPython image provided by Pimoroni that supports their RGB Keypad (find details here).
The keypad handling is pretty much the same as for my Pi Pico Keypad MIDI Step Sequencer so I won’t go over that part of the code again.
What has changed though is that I’ve removed the MIDI handling and instead inserted the “poly tone” oscillator handling code from the Pi Pico PIO Poly Tone Keyboard, including my special version of PIOBeep as described in my previous project.
The first version of the code just played a single note per key, which works and was interesting, but wasn’t really taking advantage of the polyphony now available, so I updated the code slightly to support three lists of “midiNotes” (there is still midi terminology in the code from its use in the previous projects), so that each option for each key will actually play three notes at a time.
In order to have a reasonable chance of something interesting and not just a dissonant mess, I’ve opted to use a pentatonic scale and have each key play the core note and then the one two above that, and the one four above that in the scale. This is expanded out in the three “midiNote” lists as shown below.
midiNotes1 = [ 0, # 0 means "don't play" so ignore the first value 60,62,64,67,69,72,74,76,79,81,84 # Pentatonic ] midiNotes2 = [ 0, # Dummy entry 64,67,69,72,74,76,79,81,84,86,88 # Pentatonic ] midiNotes3 = [ 0, # Dummy entry 67,69,72,74,76,79,81,84,86,88,91 # Pentatonic ]
I still need to keep a dummy “entry 0” in each list to correspond with the note being off. There isn’t much by way of error handling here – if you get the number of entries wrong in the different lists (they should all have the same entries) then the python interpreter will complain at some point.
In order to play each note, I’ve added two new functions – chordOn and chordOff. These receive an index in the midiNotes lists to play and then call the existing noteOn and noteOff functions. I now use these where I previously called noteOn and noteOff directly.
def chordOn(x): noteOn(midiNotes1[x]) noteOn(midiNotes2[x]) noteOn(midiNotes3[x]) def chordOff(x): noteOff(midiNotes1[x]) noteOff(midiNotes2[x]) noteOff(midiNotes3[x])
It is all a little crude. It would be more elegant to have a single, two-dimensional list for midiNotes so that each entry can itself be a list of notes to play, but this works fine for now.
With this configuration there are eleven notes that each key can cycle through, each with a corresponding colour as before. You can hear the results in the video above.
As I say, this is not a particularly elegant solution for the code yet, so I might work on that next. I also want to build in some simple control using the analog and digital breakout options I built into the “tone pack” module, perhaps to select different scales/chord patterns, and certainly to change the tempo of the steps.