I am using the code listed below. It is wired per this website http://rentron.com/serkey16.htm. The output from the keypad is inconsistent. Sometimes the output is correct and sometimes the output will give the correct Column but not the correct Row. Does anybody have any ideas on why this is happening?

Thanks,
Mark











'************************************************* ***********
'* Name: Turret Controller Keypad *
'* Micro: 18F452 *
'************************************************* ***********
INCLUDE "modedefs.bas"
define OSC 20
define LOADER_USED 1 ' bootloader

col VAR BYTE ' Keypad column
row VAR BYTE ' Keypad row
key VAR BYTE ' Key value
baud VAR PortA.0 ' Baud select pin
serpin VAR PortA.1 ' Serial output pin
ADCON1 = 7 'set I/O pins to digital on PORT.A
TRISA = %00000001' PortA.0 = baud select pin
INTCON2.7 = 0 ' Enable PORTB weak pull-ups
B0 Var Byte

loop:
GOSUB getkey 'Get key from keypad
send:
'IF baud = 1 THEN fast'If baud = 1 then N9600,else N2400
SEROUT serpin,N2400,[key,B0]'Send key value out PortA.1
GOTO loop
getkey:
PAUSE 50 'Debounce key-input
getkeyu:' Wait for all keys up
PORTB = 0 ' All output-pins low
TRISB = $f0 ' Bottom 4-pins out, top 4-pins in
IF ((PORTB >> 4) != $f) THEN getkeyu'If keys down, loop
PAUSE 50 ' Debounce key-input

getkeyp:' Wait for keypress
FOR row = 0 TO 3 ' 4 rows in keypad
PORTB = 0 ' All output-pins low
TRISB = (DCD row) ^ $ff ' Set one row pin to output
col = PORTB >> 4 ' Read columns
IF col != $f THEN gotkey' If any keydown, exit
NEXT row
GOTO getkeyp ' No keys down, go look again

gotkey: ' Change row and column to key number 1 - 16
key = (row * 4) + (NCD (col ^ $f))
'NOTE: for 12-key keypad, change to key = (row * 3)
RETURN ' Subroutine over

END