This project takes the Arduino Nano 12-Note Keyboard and updates it with MIDI capability!
Warning! I strongly recommend using an old or second hand keyboard for your MIDI experiments. I am not responsible for any damage to expensive instruments!
Parts list
- An existing Arduino Nano 12-Note Keyboard
- 2x 220 resistor
- male header pins
- 5 pin DIN socket or plug
- Jumper wire
The Circuit
In order to add MIDI out capability, I just need to access +5V, GND and the Arduino’s TX pin, so I’ve taken the existing circuit and wired in a few pin headers and extended the TX pin of the nano (pin 1).
Note there is a track break between the red (5V) and orange (signal) pins!
Once again, I’ve soldered the resistors required for the MIDI link inside the connector. In fact, to be honest, it’s actually the same connector from the Arduino Simple MIDI Controller anyway!
The Code
The code is basically the Arduino Nano 12-Note Keyboard but sending MIDI codes rather than playing Arduino tones. Instead of a table of frequencies for notes, I have a table of MIDI codes. For details of how to set up and use the Arduino MIDI library, see the Arduino Simple MIDI Controller.
The only thing to note is that I need to keep track of if a note is playing, still playing or has stopped. I don’t want to send continuous MIDI note on messages whilst the key is pressed, but I do want to send a MIDI note off once it is released. This is where the lastKey variable comes in. When no key is actually being pressed, this is set to -1.
Code Polyphony Update
The original code, as described above, is only monophonic – it only allows one note to be sounding at once. It isn’t a large change to make it polyphonic – i.e. to allow it to play several notes at the same time.
Essentially the code now has three lists to manage, with each list having one entry for every note supported:
- A list of pins attached to “keys”.
- A list of MIDI notes to play when the keys are pressed.
- A list of state for each each to remember if it is playing or not playing.
The basic logic of the code is now as follows
loop():
FOR EACH key on the keyboard:
Read the IO pin to see if it is active or not
IF pin is active AND note is NOT already playing THEN
Send the appropriate MIDI NoteOn message
IF pin is NOT active AND note is already playing THEN
Send the appropriate MIDI NoteOff message
This way it captures the transitions of not-pressed to pressed (to send NoteOn) and pressed to released (to send NoteOff) and it doesn’t matter how many other notes are playing at the same time as each note has it’s own state.
There is one slight complication in the code – it allows for two types of inputs – those with internal PULLUP resistors or those with external pull-down resistors. The latter makes more coding sense as if the input is read as HIGH it means the key is being pressed, but it requires extra components.
The former means less components, but means the logic of the key press is reversed (HIGH means “not pressed”, LOW means “pressed”).
This is selected by commenting out or uncommenting the following line at the top of the file as required.
//#define PULLUPINPUTS 1
It is commented out for this example as the circuit described above has resistors pulling the switches to ground when not pressed.
For more simpler circuits uncomment this line so that INPUT_PULLUP is enabled and the logic is reversed.
Closing Thoughts
This is a fairy minor addition to my board, but now I have a simple, one-octave MIDI keyboard that could actually be really useful when it comes to creating things that respond to MIDI by making sounds rather than generating them as I’ve done so far.
Kevin