Arduino MIDI Relay Drumkit

This projects links up the ideas from the Arduino Relay Bolero and Arduino MIDI Tone Module projects to create a MIDI drumkit out of relays.  This builds on concepts we’ve already met in the above projects.

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!

If you are new to Arduino, see the Getting Started pages.

Parts list

  • Arduino Uno
  • Relay modules (I used a block of four, and three individual relay modules)
  • MIDI In module (see Arduino MIDI Interfaces)
  • Breadboard and jumper wires

The Circuit

This is just a case of joining all the 5V and GND pins from the relay modules to the Arduino and assigning the signal pins from each relays to one of the Arduino digital I/O pins.  I had a block of four relays on pins 2, 3, 4, 5 and then individual relays on pins 6, 7 and 8.

The MIDI receive circuitry is hooked up to 5V, GND and the Arduino RX pin.

2020-06-14 12.26.55

The Code

Most of the concepts in the code have now already been introduced in previous projects.  There is one place where I use a programming short-hand to work out which of two values is smallest.  This works as follows:

minvalue = (value1 < value2) ? value1 : value2;

This is programming speak for “choose the smallest of value1 and value2” by calculating the expression between the = and ? and if true, returns the value between the ? and :.  If it is false, it returns the value between the : and ;

As there are now a number of lists that all need to be the same size, it is worth putting in some checking to make sure we don’t listen for more MIDI notes than we have relays, or vice versa.  Also I need a list to record the state of each relay which should be the same size as the list of relays.  Weird things start to happen if you “go off the end of a list” so it is worth putting in some basic checking code to make sure you don’t.

The other slight complication in the code is related to choosing which instruments to respond to. In the General MIDI standard, channel 10 is reserved for rhythm and so every note on channel 10 corresponds to a different untuned percussion instrument.  There is a standard map of drum kit instruments to MIDI notes, defined by the General MIDI standard, which you can see here.

But you might notice there are several variants of each instrument – “acoustic bass drum” and “base drum 1” for example.  Also, as I only have a limited number of instruments there are some sounds I might just double up on.  For example, I’d probably just assign “close hi-hat”, “pedal hi-hat” and “open hi-hat” all to the same relay.  So basically I need a way of having several MIDI notes trigger the same relay.

One way to do this might be to have more “pins” defined, but with some repeats, so for example the start of the MIDI list might be {35, 36, …} for the two bass drum sounds, which gets mapped onto {2, 2, …} so both drive the relay on pin 2.  But the problem with this is that if both sounds are used in the same piece, it becomes more complex to keep track of what state the relay was in if the other instruments wants to play.

The robust way of handling this would be to have another list that maps all the MIDI sounds we recognise onto which “drum” to play, so the structures would end up like this:

int relays[] = {2, 3, 4, 5, 6...}; // the physical pins for the relays
int relaystate[] = { LOW, LOW, LOW, ...}; // keeping track of the state
int mididrums[] = { 35, 36, 31, 38, ...};  // the MIDI notes we respond to
int drums[] = { 0, 0, 1, 1, ...};  // which relay to use for each MIDI sound

But this is starting to get quite a lot to keep up with.  In the end I went for a compromise. I define the MIDI sounds allowing three positions for each corresponding relay.  This means I can recognise three different bass drum sounds for my bass drum relay, and so on. If there aren’t three sounds I want, then just putting in “-1” rather than a MIDI note will simply skip that in the processing later on.

When it comes to picking which relay to use, when I cycle through each MIDI sound to see if that note has come in, when I find the note, I need to use the “number of MIDI note divided by 3” to get which relay to use.

As it happens, there were actually three sounds for every relay anyway.

Note that for my Yamaha keyboard, there were two extra sounds – an extra bass and snare – compared to the General MIDI standard, so I included those in too.

Find it on GitHub here.

Closing Thoughts

We are starting to get to the point of having a good understanding of how to build MIDI controllers and instruments.  But I need a bit more variety in the kinds of sounds my “instruments” can produce.

Kevin

Leave a comment