Matrix keypad code sample
Peter Jakacki
Posts: 10,193
There has been some mention of how to interface matrix keypads. I am not aware of any code that could be used as a general-purpose object so I submit a version of one I have used that is written totally in Spin.
I do not consider myself proficient in Spin as I am constantly checking the manuals for usage etc so perhaps one of you Spin gurus (Mike?) can double-check the code that was adapted from a working 4X4 keypad.
*Peter*
I do not consider myself proficient in Spin as I am constantly checking the manuals for usage etc so perhaps one of you Spin gurus (Mike?) can double-check the code that was adapted from a working 4X4 keypad.
*Peter*
{{
KEYPAD ENCODER - Peter Jakacki
Starts up a cog that scans a keypad matrix
and translates and buffers the codes.
This code was originally written as a hardcoded 4X4 (tested)
but was adapted for larger matrices (not tested)
This is a simple but complete Spin implementation
Keypad actions don't have to be fast but should be reliable so debounce periods are several ms
The keypad matrix is made up of rows (horizontal) and columns. (vertical)
All column lines are driven low while the row lines are inputs pulled high (10K).
When a key is pressed one of the row lines will become low.
The column lines are now scanned one by one to find out which column it belongs to.
When the column is found the column index is combined with the row index to form a keycode.
The keycode is translated in a user specified table and pushed into the keypad buffer.
}}
CON
bufsz = 16 ' keypad buffer size (keep in multiples of 2)
VAR
long stack[noparse][[/noparse]32]
long rows,cols,colpins,rowpins,akey,lastkey,keyrd,keywr,keycodes,ms1
byte keybuf[noparse][[/noparse]bufsz]
' Start the keypad scanner - column and row pins do not have to be adjacent
' If keypad code translation is required then set keycodeptr to address of
' translation table or else set to zero for no translation
'
pub start(keyrows,keycols,firstcolpin,firstrowpin,keycodeptr) : okay | i
rows := keyrows
cols := keycols
colpins := firstcolpin
rowpins := firstrowpin
keyrd := 0
keywr := 0
keycodes := keycodeptr ' remember pointer to user keycodes
ms1 := clkfreq / 1000 - 4296
okay := cognew(scankeys,@stack) +1 ' run keypad in it's own cog
' Returns a non-zero value if there is a keypad code in the buffer
'
pub getkey : keycode
keycode := 0
if keywr <> keyrd
keycode := keybuf[noparse][[/noparse]keyrd++&(bufsz-1)]
return
' ******************* background methods run in their own cogs ********************
pri scankeys 'main scanning loop
dira[noparse][[/noparse]rowpins..rowpins+rows-1]~ 'ensure row lines are inputs
repeat
outa[noparse][[/noparse]colpins..colpins+cols-1]~ 'drive all columns low (all active)
dira[noparse][[/noparse]colpins..colpins+cols-1]~~
lastkey := 0
repeat until row 'wait until any key is pressed
ms(5) 'oh hum, this is so boring
ms(5) 'there was a signal, debounce
if row 'double-check row again (noise?)
keypressed 'seems solid, let's try to encode it
pri keypressed | i
outa[noparse][[/noparse]colpins..colpins+cols-1]~ 'columns are always active low
repeat i from 0 to cols-1 'find out whch column is active
dira[noparse][[/noparse]colpins..colpins+cols-1]~ 'all columns inactive except...
dira[noparse][[/noparse]colpins+i]~~ 'only one column active
ms(1) 'debounce period
if row 'ignore false press (glitch)
akey := i + (( >|row)-1 )*cols 'convert row and column
if keycodes 'translate keycodes?
akey := @keycodes.byte[noparse][[/noparse]akey] 'lookup new code (usually ASCII)
if lastkey <> akey 'great! but is it a new key?
lastkey := keybuf[noparse][[/noparse]keywr++&(bufsz-1)] := akey 'yes, let's buffer it
release 'wait for button release
return
return
pri release
repeat until row == 0 'row lines are released
repeat while row 'wait if still glitching (shouldn't)
ms(5) 'debounce a further 5ms
pri row
return !ina[noparse][[/noparse]rowpins..rowpins+rows-1] & (rows*cols-1)
pri ms(period)
waitcnt(ms1*period + cnt)

Comments
I started up the buzz about the keypad, so far your code is the only one that i have gotten any response from. How did you have the
keypad wired to the prop? I'm using a 4x4 and the demo board.
attached is the schematic i have tried and some code
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Daniel Mueth
WSIU-TV Master Control
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"Just plug it in and let's see what happens"
Pins1-4 of the keypad go through a 1K to p0-3
Pins5-8 of the keypad go straight to p4-7 with 10K pull up's
Thanks
Victory Dance:
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Daniel Mueth
WSIU-TV Master Control
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"Just plug it in and let's see what happens"