Saturday, August 16, 2008

For the recent upgrade to the Toriton, I used a digital method and an Arduino board to ‘scan’ the twelve-button keypad (0-9, *, #). Previously, I had used a set of resistors acting as an array of interconnected voltage dividers, all going to a single analog input to read. Of course, this ‘analog method’ of reading the keypad is annoying to build, use and program, but it is a situation where I just didn’t know any better at the time, and used the resources and skills available to me back then.

The idea of the digital scanning of a keypad is very simple. The keypad in question has twelve buttons, set up in four rows of three (like a phone keypad, for example). Each button has two connection points – one point goes to a row pin, and one point goes to a column pin. Therefore, seven pins are connected between the keypad and the Arduino – four for the rows and three for the columns. When a button is pushed, it connects the two points – a column pin and a row pin.

By setting a row pin ‘high’ (in this case, to 5V as opposed to ground which would be considered ‘low’), and reading the digital state of the columns, and then repeating this process for the four rows, it is possible to see which button on the keypad is pressed at a given point in time.

The hardware setup is very simple – only the keypad and three resistors are required. Connect Arduino digital i/o pins 2 to 8 to the keypad. Pins 2 – 5 are for rows 1 – 4 respectively and pins 6 – 8 are for columns 1 – 3 respectively.

Anonymous said...

Hi Sebastian, thank you for sharing this. I'm curious. When using this setup, can you press more button at a time? Or are you limited to one from each row, or one from each column?

Anonymous said...

Hi Sebastian,

the Atmega series has internal pullup resistors. I think you would not need any external resistors, if you activate them.
Using these pullups you only need to let a 0 walk through your different rows instead of a 1. Reading a 0 means that key is pressed, reading a 1 means no key pressed. You end up with low active keys, but no external components except the keypad itself.

Anonymous said...

Hi Sebastian,

the Atmega series has internal pullup resistors. I think you would not need any external resistors, if you activate them.
Using these pullups you only need to let a 0 walk through your different rows instead of a 1. Reading a 0 means that key is pressed, reading a 1 means no key pressed. You end up with low active keys, but no external components except the keypad itself.

Unknown said...

As soon as you press a second key, it becomes difficult to tell which, and how many, keys are being pressed. With some clever logic (and keeping track of what the first key being pressed was), you could manage TWO keys at a time, but three is unreliable. For example, looking at a QUERTY 10-key, R1C1 means that "1" is being held down, and R1C1 -> R1R2C1C2 means that "5" is now being held down as well. However, the output doesn't change if you also hold down "4" at this point.

In most circumstances, you'd want to tell your Arduino to ignore keypad input if more than one row or more than one column was being pressed, but I guess that depends on your project.

Anonymous said...

Hi there,

In your writeup you mention that you used three resistors to connect your keypad to the Arduino. How and where are they used?

Thanks!

Anonymous said...

I've been struggling with this for weeks! If someone could post how to wire up the resistors, I would find it very valuable and would be most appreciative.

Sebastian Tomczak said...

In my example, I connected a resistor in between col 1 and ground, col 2 and ground and col 3 and ground.

misoft said...

Hi! Sorry for the "dump" question but what the keypad is used for with the Toriton? I don' understand?

Sebastian Tomczak said...

@ misoft: The keypad serves two functions 1) to set fundamental frequencies in the synthesis process and 2) to calibrate the lasers' data output

Anonymous said...

Can someone post the arduino code they used to read the keypad?