Expanding on the Pi Pico MIDI Matrix Decode project to create a basic four octave keyboard. There are some limitations with this approach though, so be sure to read on before trying to build one yourself (or skip over to Part 4 to read about the solution).
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:
- Getting Started with the Raspberry Pi Pico: Inputs and Outputs
- How to make a keyboard matrix
- Keyboard MIDI Matrix Decode and Pi Pico MIDI Matrix Decode – Part 2
- MIDI, MicroPython and the Raspberry Pi Pico
If you are new to microcontrollers, see the Getting Started pages.
- Raspberry Pi Pico
- One of the 3.3V compatible Ready-Made MIDI Modules; or
- 5-pin 180 DIN socket, 10Ω and 33Ω resistors
- Two or more circuits as described in Pi Pico MIDI Matrix Decode – Part 2
- MIDI module or sound generator (I used my Arduino MIDI VS1003 or VS1053 Synth)
This takes four of the circuits described in Pi Pico MIDI Matrix Decode – Part 2 and links them up in parallel to GP2-GP13 on the Pico, but each with its own “common” GP pin, as shown above. The boards are selected by linking them to GP28, GP27, GP26 and GP22.
Recall that there are no resistors on the board, so internal PULL_UPs are required in software.
Limitations – Ghosting!
There is a well-known problem with matrix keyboards like this, and that is “ghosting” of keypresses. Translated to this build, it means that if, say, you are pressing C, E and G on one of the boards, then pressing any of C, E or G on any of the other boards will also trigger C, E and G on that board too. You can hear the effect at the end of the video – a chord is pressed on the lowest board, but you can hear the chord re-sounding at higher octaves when additional keys are pressed.
This is a bit of a problem if you are trying to play the piano… but then, I wasn’t really suggesting that you’d be able to play Chopin on tactile switches!
A full detailed explanation of the problem can be found here. The solution is using diodes on all the switches – so one diode per switch. But even though I knew that would be ideal, it was really a bit of a step too far for me and my playing around with stripboard at this time.
Update: I couldn’t let it go, so decided go retrofit some diodes – read about it in Pi Pico MIDI Matrix Decode – Part 4.
This is using the same Micropython code for the Raspberry Pi Pico as used previously, but now, in addition to the pin-mapping for the “rows” of switches, we also have definitions for several “columns” too.
# Switch OFF will be HIGH (operating in PULL_UP mode) row_pins = [3,2,5,4, 6,8,7,10, 9,12,11,13] col_pins = [28, 27, 26, 22]
One issue is that we really need the column pins to be initialised in OPEN_DRAIN mode this time. It wasn’t a major issue for the first project, but we will get weird things going on if we can’t turn off columns that we don’t want to use. There is work going on to implement a simulated OPEN_DRAIN mode in the RP2 version of Micropython, but I still don’t know if it has made it to a release yet (although I suspect it was probably in v1.14).
The way the emulated OPEN_DRAIN mode works though is to set the pin to an INPUT when set HIGH, which is effectively the same as creating a high impedance open drain output (as I understand it). So I’ve used that trick in my code for now too:
for c in range(0, numcols): cols[c].init(mode=Pin.OUT) # Emulating OPEN_DRAIN cols[c].value(False) # Rest of the code acting on this column cols[c].init(mode=Pin.IN) # Emulating OPEN_DRAIN
I still can’t do anything about the ghosting though (at least without significantly more complicated code, if it is possible at all).
Having built these boards, there is a part of me that wishes I’d taken the extra effort to add diodes to avoid the ghosting – but at the time I opted not to, and I’m probably not going to be doing anything more fancy, so it probably was the right choice (Update: I changed my mind).
It might be nice to actually design a PCB to support an octave of switches like this though. If I did, I would try to both add the required diodes and find a way to link then up without requiring lots of cables. The pull of the cables was so much that I had to fix the boards down to use them… which might have been a mistake too – they are only cheap stripboard, and might not survive being taken up again!
Assuming I can get them off again though, they might have some potential for some of the other messing about I have in mind too.