PDA

View Full Version : another way to get a keyboard matrix to work off 1 adc pin



longpole001
- 29th April 2013, 16:55
Hi guys have been looking at connecting a 4 x4 matrix keyboard via 1 adc pin on a pic , ( yes i do like to not waist pins if i can help it ) found this around the internet as some one has done it in basic .

It was noted that the on resistance of each key needed be consistent even over time to ensure this to work correctly.

My question is ,
1. has anyone tried this at all , and how would membrane keys pad go with consistency using ACD.
2. has anyone tried using self learn routine on a ACD input such that a keyboard "on" resistance changes over time that it can adjust without input from the user to accommodate for change over time - may be a hard ask of a routine ?
6984


; One keypad (3x4) to one ADC pin, all Atoms
; 28 January 2010 By Ken Jennejohn
; Wiring: check wiring diagram supplied with post (this is now a 3x4 keypad!)

;****** Variable Assignments *******
kpad_in var word
old_kpad_in var word
old_kpad_in = 0
key var byte
old_key var byte
result var word

result = 0
looper var byte ; for loops less than 256
bigloop var byte

pause 1000 ; Needed for PIC to initialize internally

serout s_out, i19200,[0, 7] ; clear the screen, sound terminal "bell"

MAIN
; Initialize main variables
key = "X"
result = 0
kpad_in = 0
old_kpad_in = 0
;Is a key pressed (ADC reading less than 900)? If not, go back to MAIN.
ADIN P6, kpad_in
IF kpad_in > 900 then MAIN
; Falls thru when key pressed...

; These two loops look for a legit key press, and determine which one.
pause 50 ; This allows keypad switch to finish "bounce"
FOR bigloop = 1 to 3 ; has to ID same key three times to pass
FOR looper = 1 to 10 ; read keypad input 10 times
ADIN P6, kpad_in
; keypad switch "bounce" handled next

; Uncomment the next line for troubleshooting
;serout s_out, i19200, [dec (ABS(old_kpad_in - kpad_in)), 13]

; The difference between this key press and the last must be
; less than ten. We use the ABS(olute) modifier to keep results
; positive and avoid negative results. Greater than 10, do it over.
IF ABS (old_kpad_in - kpad_in) > 10 then
old_kpad_in = 0
looper = 0
result = 0
ENDIF
result = result + kpad_in
old_kpad_in = kpad_in
next ; looper
; get average of readings
result = result / 10

; This next output routine is available for troubleshooting, just uncomment it.
;serout s_out, i19200, ["result: ", dec result,13]

; We next do a gosub to routine that determines which key has been pressed
gosub Key_Is_

; Upon returning, we determine if the key was properly determined
IF key = "X" then MAIN ; If key still "X" we failed
; If passed, we save it to check later. Must pass this three times to accept key press value.
IF key <> old_key then
bigloop = 0 ; If comparison fails, restart bigloop
ENDIF
old_key = key ; it's OK, save latest key value

next ; bigloop

; If key press looks good after three tries we report it here and sound terminal "bell".
Report_
serout s_out, i19200, | ; We use pipe symbol (the "|") to continue to the next line
[key, 7] ; clear screen, home cursor first

; We wait here for key release
stay_here_
ADIN P6, kpad_in
IF kpad_in < 900 then stay_here_

; And then we do it all over again.
GOTO MAIN

;****** SubRoutine(s) ******
Key_Is_
; Uncomment the next line for troubleshooting
;serout s_out, i19200, ["key_is_ result val: ", dec result, 13]
IF result > 592 AND result < 602 then
key = "1"
ENDIF
IF result > 615 AND result < 625 then
key = "2"
ENDIF
IF result > 640 AND result < 650 then
key = "3"
ENDIF
IF result > 425 AND result < 435 then
key = "4"
ENDIF
IF result > 465 AND result < 475 then
key = "5"
ENDIF
IF result > 502 AND result < 512 then
key = "6"
ENDIF
IF result > 695 AND result < 705 then
key = "7"
ENDIF
IF result > 710 AND result < 720 then
key = "8"
ENDIF
IF result > 725 AND result < 735 then
key = "9"
ENDIF
IF result > 778 AND result < 782 then
key = "0"
ENDIF
IF result > 0 AND result < 0 then
key = "A"
ENDIF
IF result > 0 AND result < 0 then
key = "B"
ENDIF
IF result > 0 AND result < 0 then
key = "C"
ENDIF
IF result > 0 AND result < 0 then
key = "D"
ENDIF
IF result > 768 AND result < 772 then
key = "*"
ENDIF
IF result > 790 AND result < 801 then
key = "#"
ENDIF

return

_________________
kenjj
http://blog.basicmicro.com/
http://kjennejohn.wordpress.com/

Heckler
- 29th April 2013, 18:42
This keypad is not a "matrix" but rather 12-13 individual pushbuttons but you might gane something here...

Here are a couple of videos I ran across a while back where this guy uses a similar method to read a keypad using just one pin.

Great nostalgia if you were around in the mid 70's and remember phone phreaking.
Especially if you dig deeper on the projectMF web site they have some old recordings of guys phreaking(hacking) the telephone network to make free long distance calls.

If you are say only in your 20's now you might say "What is long distance??"


http://youtu.be/hxMA_2F4AaM

http://youtu.be/Kow8_N_dNts

And if you follow this link you will find the code and schematics of his project

http://www.projectmf.org/

longpole001
- 30th April 2013, 21:42
i was wondering if anyone has a done a 1 pin ADC of 16 key matrix keyboard using a membrane keypad . I have not used many membrane keyboards , and wondered if the resistance varies a lot of per switch / batch ?

wdmagic
- 30th April 2013, 23:56
no its fine, thats what i was trying to use when I first started with keypads, I just dont like useing ADC for a keypad.
you can always send the ADC results to a LCD before programming the numbers in for accuracy.

longpole001
- 1st May 2013, 01:23
if to be used for multi products and is reliable methord or is the standard 8 ports approach required

wdmagic
- 1st May 2013, 01:52
Personally i like to use the 74C922N IC's for interfacing keypads, it uses 1 interupt and 4 data lines for a binary input, there are normally 3 basic ways of handling keypads (there are more but they are more rare)
1.ADC Keypad IO (uses only 1 pin, Slower, More code space, must set up polling)
2.Serial Keypad (uses 1-3 pins based on IO type, fast, still need to set up polling) possible to add extra pin for firing a Interupt
Article on making a serial keypad (http://www.picbasic.co.uk/forum/showthread.php?t=5354) You will have to modify this code, or look on internet on making serial keypads
3.Genuine keypad IO (5 pins, Interupt based - instant results, no polling needed)
Article where I got mine working (http://www.picbasic.co.uk/forum/showthread.php?t=17925)

tasmod
- 1st May 2013, 16:22
That would be a handy way to do a keypad for radio use.

I have a project in build at the moment which strobes the keypad lines, unfortunately this generates interference in the receiver.
Using decoupler caps prevents the strobe. Using ferrite bead chokes reduces the output of each line.

I'm using a 4x3 keypad as it suits my needs.

With precision resistors this could be a good way to do it once the ADC values have beeen determined for each keypress.

Rob

longpole001
- 1st May 2013, 22:03
Hi guys,
the thing that worries me about the adc approach is that

Each keypad is likely to have a different resistance values either ........
a. At keyboard / membrane manufacture time - so ADC value / overlap per key range may not give uniform approach at assembly time
- so each keypad would need to be adjusted and setup each time, before it will work correctly in the application

b. Over time keypad is likely to ware and with it resistance values change over time , so the program may need to have a " learn function " to get each key work again( ADC range change),
this assumes that key ADC ranges do not overlap due to 1 key being of lot higher resistance , in which case the keypad would need to be replaced

The approach for having a separate chip that controls the keypad is appealing , in that it frees up the main controller some what , but adding extra chips is a cost that may be better to be placed into a larger PIC that has higher I/O pin count and going the standard matrix i/o approach , if doing from the outset, for multi products. depends on your needs.

There a few display serial products out there that allow for keypad directly interfaced to the LCD controller. but they are not a cheep option when doing a few units

I do intend to try the ADC approach and hammer the test keyboard for about a week to see if the key ACD ranges change as some ware starts in.

I do think a relearn program is easy enough to do ,assuming some LCD to allow user to adjust key "x" or just start from key x to y following each column, row and use the results
but it all takes time , and code space

Still looking for input from those that have tried and tested this approach , or have used it in product manufacture where more than 1 or 2 were made and get feedback on what results they had over time

Cheers

Sheldon
;)

Demon
- 1st May 2013, 23:51
Never tried this. I'd suggest looking at a supplier like Digikey and seeing what precision of resistors you can afford (1% are the best, by memory).

Then do some calculations and see how much your values can drift, up and down.

Robert

longpole001
- 2nd May 2013, 04:15
resistors not the problem its the switches "on" resistance over time .

Even the best switches have a range of resistance from manufacture , the higher quality switches dont tend to change as much as time goes on with ware , but membrane ones i am not so sure ,
I am sure some one here has used membrane switches and hopefully using this method to see how the long term effects are

wdmagic
- 2nd May 2013, 05:14
its a miniscule change, with propper resistance spacing and code to allow a wider range its not an issue, ive with a 8bit in you can set it as a example of 0-16-32-48 etc.. and its going to line up right in the middle of those numbers if you do it right so any play will still be caught in the range... however ADC keypads have major errors if 2 or more keys are pushed cause that just sends eratic results.pushing 3 and 9 might give you 4, who knows.

longpole001
- 2nd May 2013, 22:33
thanks , ill have purchased 30 membrane panels as a starting point , and will give the adc a go , to see if the "on" values are same ,then ill hammer one to death , see if it changes values radically , its the best way i can think of to see if there are issues

i think the speed and polling time will probably be more the undoing of the approach, with all the other things the pic has to do

cheers

sheldon

Demon
- 2nd May 2013, 23:11
Heat and cold might also be a good stress test (freezer & oven). Pretty sure temperature will affect resistance though.

Depends if your product will always be used at room temp.

Robert

Jerson
- 3rd May 2013, 05:13
Seriously, however tempting a 1 pin keyboard might sound, I'd steer clear from it. I've seen enough examples of 1pin keyboards going bad after a few years in operation. Whether it is contacts getting tarnished, or just aging of components; whatever. For a good professional product, I strongly recommend a proper digital matrix instead of a 1 pin ADC technique.

The technique itself is workable as you will find out after you are through with your trials.

wdmagic
- 3rd May 2013, 11:08
Another way to run the keypad might be to use a series of capacitors instead of resistors, and have the oputput tied to a 555 timer with fixed resistors so that the kaypad actually changes the frequency which could be a large range and output to the PIC, then instead of using the ADC IN, use PULSE IN, so that instead of counting milivolts from a adc, you could count a large range of pulses.
Just an idea.

Add On: not sure if it would work though, might have to ad a cap in parallel with entire pad since the 555 would need a cap even if the keys are being pressed

longpole001
- 4th May 2013, 01:23
yes that be interesting to try , if for no other reason than to see if can work , not sure about the extra chip count to achieve ,

in the end i like reliable and consistent in keyboards
if Jerson says he has seen the 1 pin adc failures , then its likely that the approach has been used in commercial products. but with all things its depends on the usage as well , enviroment etc

the application i have is not in wet environment,but is used outside and is covered , key usage for the membrane is for some programming and not heavy usage even then.

the application requires serial lcd display , keypad , serial port to pc via serial to usb adaptor , 3 other special allocated ports for a outputs , 4 other spi devices on a bus, i still will have 3 other switches which will not be on keypad , bottom line is i/o pins are in short supply unless i start to look at a larger pic , which maybe the way to go, but i am resistant to go purchase another pics at this point in the design

.