Go Down

### Topic: Matrix Keypad - Optimisation (Read 12110 times)previous topic - next topic

#### pracas

##### Oct 22, 2009, 04:53 am
Triggered by a question to reduce pin usage for matrix keypads, I was thinking of this...

• To each input of the keypad connect a fixed resistor - a different known value with significant difference in resistance for each input. and connect them all in parallel to a digital output pin on arduino
• Calculate what will be the drop in 5v when it passes through each of the resistors
• wire the inputs up from the keypad in parallel and hook it up to an analog input
• based on the values read you will be able to identify from where it originated

Will this work?

I will test it and post results however any suggestions are welcome.

Cheers,
Pracas
Be The Change...

#### jezuz

#1
##### Oct 22, 2009, 04:58 amLast Edit: Oct 22, 2009, 05:00 am by jezuz Reason: 1
I believe that is how button matrices work, so yes, it should work as you described. Your don't necessarily even need to do the calculations, as you can just do a few test runs and see what values you get from the analog_in for each different button pressed.

EDIT: one thing I am not sure about is your step 2, the one involving the connection in parallel to a digital out... why do you need this?

#### pracas

#2
##### Oct 22, 2009, 05:08 am
to use a single pin as input and a single pin to read output. so we can work out all sizes of keypads on 2 pins. Thats the idea.
Be The Change...

#### Jeremy D Pavleck

#3
##### Oct 22, 2009, 07:27 am
That would work fine, but how will you ensure that only 1 button is pressed at a time, and no one is hitting 2 or more - either by mistake or on purpose?

#### pracas

#4
##### Oct 22, 2009, 09:54 am
I think the initial idea wont work. Because there wont be any load the resistance might not actually show a decrease in voltage. So here what is currently being tested

Hook up 8 different resistance to the 8 pins of a 4x4 key pad. Wire 4 of the row or column pins to 5v supply directly and the rest 4 in parallel to an analog input and measure voltage / compare it to preset values. if we ensure that the resistance values don't add up to similar combinations, then we might even be able to avoid multiple presses. Will keep this updated.

Cheers,
Pracas
Be The Change...

#### pekkaa

#5
##### Nov 02, 2009, 08:37 amLast Edit: Nov 02, 2009, 01:25 pm by pekkaa Reason: 1
Quote
To each input of the keypad connect a fixed resistor - a different known value with significant difference in resistance for each input. and connect them all in parallel to a digital output pin on arduino

Why would you need a digital out pin? Can't you use Vcc instead?

EDIT: Should have read more carefully. You already told you won't use digital out after all.

Quote
Wire 4 of the row or column pins to 5v supply directly and the rest 4 in parallel to an analog input and measure voltage / compare it to preset values.

#### pekkaa

#6
##### Nov 02, 2009, 10:27 pmLast Edit: Nov 03, 2009, 12:16 am by pekkaa Reason: 1
This is probably something like you were thinking of, although for 4x3 keypads:

Resistors R_row1 and R_col1 can be 0 ohms, so they are not really needed. R_d is a voltage divider resistor. It also works as a pull down resistor when no key is pressed. Here is also an OpenOffice spreadsheet for calculating the resistor values: http://www.siterunner.fi/liitteet/outijapekka/materiaalipankki/5.ods . I haven't tried it yet, so I am not really sure if it works.

EDIT: Small error in the schema.

#### pekkaa

#7
##### Nov 04, 2009, 12:30 pm
I managed to put it together. I works in princible, but is barely usable. The problem is that the reading from analogIn is not stable. It takes a long time (like a second or maybe more) before the reading from ADC stabilise.  I could be possible to implement some kind of filtering, but wouldn't still respond quicky enough to  a key press.

Perhaps the problem is wrong kind of keypad. Mine was ripped from an old phone. Is has rubber keys that short circuit the contacts on the PCB when a key is pressed. A tactile keypad with proper switches may work better. I also used quite big resistor values and long wires. Maybe there is too much impedance that causes the lond delay before the reading from analog in stabilises.

#### pracas

#8
##### Nov 04, 2009, 01:07 pm
I managed to try it and it did work. But noise can blow up the whole thing. I think it would be better than a regular keypad in terms of response rate as the scanning is limited to a single pin and then lookups.
Be The Change...

#### pekkaa

#9
##### Nov 04, 2009, 03:01 pmLast Edit: Nov 04, 2009, 03:01 pm by pekkaa Reason: 1
Quote
I think it would be better than a regular keypad in terms of response rate as the scanning is limited to a single pin and then lookups.

What do you mean by response rate? Do you mean the number of keypresses per second you can read? In my implementation is was quite the opposite, the response rate was very slow because I had to wait the reading from analog input to stabilise, i,e., it took long time before the voltage rose after I pressed a key.

What resistor values did you use?

#### olson

#10
##### Nov 04, 2009, 09:27 pm
Maybe something else could be used like send a serial signal from the keypad. Did a quick search and found this.

http://www.rentron.com/Ser-Key.htm

Its not as simple as using only resistors but it would probably be more reliable and easier to code for. Or if not serial then maybe a morse code like signal could be sent from the keypad. Overall the circuit would be more complex but it would use less pins on the Arduino. Cheers!

#### Udo Klein

#11
##### Nov 04, 2009, 10:55 pm
The resistor approach would not work even if noise would not be present. There are some LCD shields with a similar setup (but less resistors). This works "mostly". The issue is temperature drift. You resistors can drift enough to be detected as the wrong one --> will fail especially in summer.

The standard approach is to go for shift registers. This is described in the playground. You can either use a shift register for reading or you can use a shift register for pulling low keys in order to read if they are pressed. The second approach would require one bit more but would allow to pull all low at the same time. Then this could be detected during an interrupt which then determines which was actually pressed.

#### pekkaa

#12
##### Nov 05, 2009, 08:50 am
Quote
The resistor approach would not work even if noise would not be present.

Perhaps will we can still have a usable solution if we have an own analog input for each column. For 4x3 keypad we will then need 4+1 resistors (one for each row and one divider/pulldown resistor) and three analog inputs, which is still less than seven pins it will require if we connect the keypad directly to Arduino's digital inputs.

Quote
The standard approach is to go for shift registers.

That is certainly a better way to do it. I will probably go that way if I am going to use the keypad for something real. Unfortunately I don't have a shift register around, but I have bunch of resistors instead.

#### Carl R

#13
##### Nov 25, 2010, 12:12 am

270 ohm between the column pins.
1K ohm between the row pins.

5v is connected to column 0 as follows:
5V--Col0--270--Col1--270--Col2--270--Col3

the analog input is connected to row 3  with a 2.7K resistor between it and ground as follows:

this will give the following values of resistance divided against the 10k keys listed are from col0, row0 to col3, row3

the Vdrop is the voltage drop across the keypad matrix

the analog value is the calculated value the arduino will read

the range is what I figure could be defined as the min max for each button with a bit of a buffer between each range

I used a spread sheet to figure this all out and rounded it

Button       R                Vdrop      Vout     Analog Val.    Range
1 -         0 ohms             5V          0V            0             0-38

2 -        .27k ohms         4.55V      .45           93           55-125

3 -        .54k ohms         4.17V      .83           170         138-190

4 -        .81k ohms         3.85V      1.15         236         217-250

5 -        1K ohms           3.65V      1.35          276        270-298

6 -        1.27K ohm        3.4V        1.6           327         306 - 347

7 -        1.54K ohm        3.18V      1.82          371        353 -384

8 -        1.81K ohms      2.99V       2.01         410         399-420

9 -        2K ohms          2.87V        2.13         435        430-450

10 -      2.27k ohms      2.72V        2.28         467        455-480

11 -      2.54K ohms      2.58V       2.42         496         485 - 500

12 -      2.81k ohms      2.45V       2.55         522         515 - 525

13 -      3K ohms          2.37V       2.63         538         530 - 545

14 -      3.27k ohms      2.26V       2.74         560         550 - 565

15 -      3.54K ohms      2.16V       2.84         580         570 - 585

16 -      3.81K ohms      2.07V       2.93         599         590 - 610

perhaps it would be easier to just say Calculated value +/- 10 which is limited by the resolution toward the end of the list. I would think that would be enough of a range.

I haven't tested this yet, but plan to soon; There may be better values of resistors to use, but I think this will work.

Theoretically if there were any concern about the value of the resistors changing they all would likely do so and should keep the same output voltage

If you see any major flaws to my reasoning, please let me know.

-carl

PS i tried using the table tool, but it made little sense and couldn't find info on how to properly use it

#### Carl R

#14
##### Nov 25, 2010, 09:45 am
I've been trying to figure out how to interface a keypad with fewer than 8 inputs on the arduino using a single analog value.  upon playing with the values I found it very difficult to find the proper values as the difference in values toward one end becomes very miniscule. there's an instructable for a 3x4 keypad, but modifying it to 4x4 makes it imperative to use very tight tolerance resistors (1%)

that said, I found two decoder IC's, that will put out a 4bit parallel or serial value that runs off the arduino clock.

This one seems simpler ede1144/p by elab
https://www.jameco.com/Jameco/Products/ProdDS/171969.pdf

and this one is 74c922 by Fairchild

anyone have any experience with these chips?

I'm leaning toward the elab,

Any input would be much appreciated.

-carl

Go Up

Please enter a valid email to subscribe