Analog Keypad Tone Controller

I’ve picked up a couple of cheap 3×4 keypads so thought I’d look at its potential as a music controller.

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
  • 3×4 “RobotDyn” analog output keypad (see here)
  • 1x 220Ω resistor
  • 1x 8Ω speaker or headphone
  • Breadboard and jumper wires

The Circuit

AnalogKeypadToneController_bb

These keypads are interesting as they have 12 buttons but only use three pins – OUT, GND, VCC.  They work on the same principle as my Single Pin MIDI Channel Selector – namely that the different buttons result in different resistors being switched in, resulting in a different voltage on the OUT signal.  Consequently they need hooking up to an analog pin.  Mine looks like the following.

RobotDyn-Keypad

If you look closely you can see there are six surface mount resistors at the top of the board.  On the back of the board is a “key” detailed the different voltage readings to expect from which switches given 5V power and a 1024 bit analog input range – i.e. as you’d expect from an Arduino Uno.  I’ve poked about a bit with a multimeter and a magnifying glass and think the layout and circuit is as follows.

The basic operation is a series of circuits where the output is pulled low when no switches are pressed, but as soon as a switch is pressed, we get a circuit like the following:

AnalogKeypad_schem-exract

I.e. a potential divider using a combination of one of the first sets of three resistors combined with one of the second sets of resistors as one part of the divider, and the 10kΩ to GND as the other.  By my calculations this generates the following table.

AnalogKeypad_Resistors

These calculated 0-1023 values do seem to compare pretty favourably with those printed on the back of the boards. Note for some reason (I guess to mimic a phone keypad) the bottom row of switches is labelled 10, 0, 11.  I’ve ignored this and called them 10,11,12!

IMG_5187

I’ve used two of them, each hooked up to a different Arduino analog input pin (A0 and A1).  I’ve also attached an old loudspeaker via a 220Ω resistor to pin 9.  You can add as many keypads as you have analog pins.  I wish I’d picked up a few more now!

The only downside, is that they don’t really do multiple switch presses very well.  Well, to be honest, they don’t really do multiple keypresses at all.

The Code

The code is very similar to my Single Pin MIDI Channel Selector.  The basic idea is to read the analog input, match the reading to the known cut-off points as described above for the resistances, and use that to decide which switch was pressed and thus which Arduino tone() to play.

Here are the main parts of my “switch reading” code.

#define NUM_BTNS 12
#define ALG_ERR 8
int algValues[NUM_BTNS] = {
  1023,930,850,   790,730,680,
  640,600,570,    540,510,490
};

uint8_t readSwitches (int pin) {
  int val = analogRead (pin);
  for (int i=0; i<NUM_BTNS; i++) {
    if (val > (algValues[i] - ALG_ERR)) {
      return i+1;
    }
  }
  return 0;
}

I have an array to store the analog values I’m expecting.  I’ve included a margin for error in each reading (ALG_ERR) and start comparing with the highest value first.  As soon as a match is found, that is the button number to return, switching from a 0-11 based index to a 1-12 based index, so that I can reserve 0 for “no buttons pressed”.

As this function takes the analog pin to read as a parameter this can be used for any number of keypads in turn.

The only remaining thing to do is to turn the read values into a frequency for the tone function and play them.

Find it on GitHub here.

Closing Thoughts

I really wasn’t expecting much from a £3 or less unit, but actually I’m pleasantly surprised by these modules.  They are very clicky, but that adds somewhat to their charm.  Only being able to read a single switch does limit them somewhat, but I don’t think it will much.  I really should add the key caps onto mine now.

Some ideas of future projects include:

  • Generate MIDI note messages rather than tones.
  • More complex key-matrix drum machines.
  • MIDI control message generators.
  • A “preset” set of voice selectors using MIDI program change messages.
  • Adjusting the frequencies to create a micro-tonal player.

An Arduino Uno can easily scan six of these boards.  A Nano could scan eight.  I’m seriously tempted to order some more now…

Kevin

Leave a comment