Arduino MIDI Button Voice Select

Having got as far as an Arduino MIDI Button Bank Selector I went off an ordered some cheap 8-way button pcbs so I can start to experiment with a voice selector too.  As I think I mentioned before, I’d really like a set of buttons like you’d find on a real synth 🙂

This is the first go at getting something working on a solderless breadboard.

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 Arduino, see the Getting Started pages.

Parts list

  • Arduino Uno or Nano
  • For USB MIDI: Arduino compatible Pro Micro (or other ATmega32U4 board)
  • 5 banks of 8 buttons (see photos – I searched for “matrix 8 keypad” using online auction or Chinese marketplace sites)
  • For serial MIDI: MIDI interface
  • Breadboard and jumper wires
  • A synth module to control. I’m using my MiniDexed.

The Circuit


The diagram shows five banks of 8 switches plugged into an Arduino Uno.  They are wired in a “matrix” format – each of the eight switches is connected to D2 to D9 on the Arduino; then each module has its own “common” IO pin – I’m using A1 to A5 in digital pin mode.  I’ve not shown every one of the eight wires to every module to keep the diagram relatively clear, but all eight wires must be connected from each module to D2 to D9.

The basic operation is that D2 to D9 are configured for INPUT_PULLUP, but A1 to A5 are configured for digital OUTPUTs and all set HIGH.  Then each of A1 to A5 is pulled low in turn and then if any of the buttons are pressed on that module, then the corresponding D2 to D9 pin will read LOW.  But we don’t really need to think about that as it is all handled by the Arduino Keypad library.


One thing we do need to note though is how the buttons are wired to the header pins.  The order is as follows (in the orientation as shown above):

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

For serial MIDI output, a MIDI module needs to be connected to TX, 5V and GND.

If USB MIDI is required, then an Arduino with native USB is required – i.e. one based on an ATmega32U4 such as a Leonardo or a Sparkfun Pro Micro.


The Code

I’m using the Arduino Keypad library, which can be installed via the Arduino Library Manager in the usual way.  It is worth just testing the wiring first using one of the example sketches.  I’ve used the “customKeypad” sketch using the following key matrix.

#include <Keypad.h>

const byte ROWS = 5;
const byte COLS = 8;
char hexaKeys[ROWS][COLS] = {
{ 4, 20, 3, 19, 2, 18, 1, 17},
{ 8, 24, 7, 23, 6, 22, 5, 21},
{12, 28, 11, 27, 10, 26, 9, 25},
{16, 32, 15, 31, 14, 30, 13, 29},
byte rowPins[ROWS] = {A1, A2, A3, A4, A5};
byte colPins[COLS] = {2,3,4,5,6,7,8,9};

Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);

void setup(){

void loop(){
  char customKey = customKeypad.getKey();
  if (customKey){
    Serial.println(customKey, DEC);

The rather odd ordering is to keep the wiring simple.  This matches the orientation of the keypad modules as shown in the diagram (and photos).

To map this over to MIDI messages, I’ve 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.


The main loop is relatively simple, as the Keypad library is doing most of the work.  Note that key is 1-indexed and that values greater than 32 are treated as bank selections, not voice selections.

void loop() {
  char key = kp.getKey();
    if (key) {
      if (key <= NUM_VOICES) {
      // Voice/Patch change
      midiPatchChange (key - 1);
    } else if (key <= (NUM_VOICES+NUM_BANKS)) {
      // Bank select
      midiBankSelect(key - NUM_VOICES - 1);

Find it on GitHub here.

Closing Thoughts

If I had a 3D printer, I’d be printing out a case and set of buttons that matches the styling of a DX synth with physical buttons!  But I don’t, so I’ll have to make do for now…

But this is absolutely shouting “make into a standalone module” to me, and if I used a Pro Micro, I could make it fully USB and self-contained for plugging into my MiniDexed!  If I was feeling more adventurous I’d even build in the MiniDexed display and rotary encoder to make a fully “DX7 in a box” complete with all patch buttons.

Of course, as this is just sending standard MIDI BANKSEL and program change messages, you can mirror the voice selection configuration of any of your favourite synths!  And if you need more buttons, there are still more IO pins that could be used to index into additional modules.  As shown, with an Uno, D10-D13 and A0 are still free, giving the option of five more modules.  If you use a different Arduino board you might even have more.


3 thoughts on “Arduino MIDI Button Voice Select

    1. There isn’t really a single supplier, but I added a note that searching for “matrix 8 keypad” seems to find plenty in the usual places 🙂 To be honest, any similar module should do the trick.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s