Matrix Keypads

(Or, Why Your Keyboard Doesn't Have One Hundred and One Wires Sticking Out of It)

There is still a definition of "matrix" that isn't covered here. In electronics, a "matrix" is a method of multiplexing multiple input or output lines onto a grid, in order to decrease the number of control lines needed for I/O. Perhaps a demonstration is in order.

As you may or may not be aware, a simple logic switch circuit usually looks something like this:

             button
             __|__      low res.
Input >---+--*   *------/\/\/----> +Vcc
          |             i.e. 10KOhm
          >
          > high res.
          > i.e. 1MOhm
          |
         === 
          =  GND

When the switch is not pressed, the input is pulled to ground (which is usually logic zero) through the resistor. When the switch is pressed, the lower impedance resistor overrides the higher one, and the input will be pulled high (logic one). (If you don't have a background in electronics, you may wonder why the two resistors and connection to ground are required at all; the reason is that, without them, the input would be left floating (not electrically connected to anything) when the button is not pressed, and that's a very bad thing where digital logic is concerned.)

Now, you could create a set of keys by just repeating this circuit, but you would need a separate input pin for every single key! This might be fine for four or five keys, but not for a 16-key keypad, or an entire keyboard. So we multiplex multiple keys across each input pin.

Let's say, for simplicity, we have a 3x3 keypad, as below:

            Strobes
         A     B     C
         |     |     |
         >     >     >
         >     >     >
         >     >     >
         |     |     |
I 1 -----O-----O-----O---/\/\/---+    
N        |     |     |           |
P        |     |     |           |
U 2 -----O-----O-----O---/\/\/---+
T        |     |     |           |
S        |     |     |           |
  3 -----O-----O-----O---/\/\/---+
                                 |
                                === 
                                 =  GND

In this diagram, each of the O's represents a switch, which when depressed, forms an electrical connection between a horizontal line and a vertical line. If, for example, switch B1 is pressed, lines B and 1 will be shorted together.

Now, this circuit as it stands isn't going to be very helpful, because nothing is connected to anything. But if you just connect all the strobes to logic high at once, you're going to have a problem: any one of the switches on a row will pull that input high, and you won't be able to distinguish which column caused it!

The answer lies in the name of the strobe lines: we take turns turning each one on, reading the input pins, and then turning the strobe off and moving on to the next one. This is, as you might guess, called strobing the pins. It is done fast enough that it's not possible for the microcontroller (or whatever is connected to the inputs) to "miss" a keypress on one strobe while it has another strobe turned on. The algorithm for reading the keypad diagrammed above would look something like this:

Turn off all strobes.
While (program is running)
{
  Turn on strobe A.
  Wait a few microseconds for circuit to stabilize.
  Read input pins (these are the states of keys A1, A2, and A3).
  Turn off strobe A.
  Turn on strobe B.
  Wait a little while again.
  Read input pins (B1 to B3).
  Turn off strobe B.
  Turn on strobe C.
  Wait a bit once more.
  Read input pins (C1 to C3).
  Turn off strobe C.
}  (Loop back to top)

Pretty simple, isn't it? There are a few other electrical design details, of course: you would typically want the strobes to only be driven strongly (meaning the connection to positive voltage is through a resistor with low impedance) when high, and to be driven very weakly or be left floating (known as Hi-Z meaning "high impedance") when low1; otherwise, the strobes could potentially "fight" each other to drive an input line. You would probably also have diodes at each of the key locations, so that current could only flow from the strobe lines to the input lines, and not the other way around.

This same procedure can be used for outputs, instead of inputs -- instead of reading input pins, you set output values, and place output devices (such as LEDs) at the junctions where the switches would be. If each strobe line goes "high" when it is being strobed, than setting an output line "low" will cause current to flow from the high strobe line to the low input line, lighting that LED (or whatever is at the junction). The trick is that the strobing has to be fast enough that the LED refresh rate will be faster than the human eye can percieve, or they will appear to flicker2. This is how large LED scoreboards and displays (like the Jumbotron) operate, and is also the basic principle behind LCDs and other matrix displays. (And it's a good thing, too; can you imagine a 640x480 LCD panel requiring 307,200 output pins!?)

You can even use the same strobe lines both for monitoring input lines and setting output lines, further cutting down on pin count! Many front-panel interfaces such as those on refrigerator ice dispensers and vending machines operate in this fashion.

Finally, in the end, the real reason why your keyboard doesn't have 101 wires sticking out of it is that the matrix encoder is built right into the keyboard. The data is then transmitted serially over the PS/2 interface to the computer. If you've ever had a keyboard spit out spurious keypresses at random, or output the wrong codes for certain keys, the malfunction is almost certainly due to a damaged matrix encoder, or possibly a short or open circuit in the key matrix itself.

Now you know, and knowing is half the battle.

1On some microcontrollers, outputs that are strongly driven when high and Hi-Z when low are called multi-drive pins.

2Incidentally, if you were to purposely slow the strobe rate down far below the speed of human perception, and pull all of the output lines low, you will have just created a set of chaser lights!