PDA

View Full Version : 3x4 keypad scanning problem and others



pt3rg
- 28th November 2003, 10:39
I got a couple of questions to ask some of you very smart people here. :)

I'm testing a program for scanning a 3x4 keypad and a yellow LED is supposed to light up whenever a key is pressed. The problem is the LED only lights up if i press keys from the 2nd and 3rd column, it doesn't give any response if i press keys from the 1st column (1,4,7,*).

1st column - RB0
2nd column - RB1
3rd column - RB2
1st row - RB3
2nd row - RB4
3rd row - RB5
4th row - RB6

2. And how do i set up an administrative password where the password is already in EEPROM location 0 when the system starts up? Do i use the DATA function? If the admin password is 1234, the user has to key in 1234 then only a green LED will light up.

DEFINE LOADER_USED 1
i VAR byte
col VAR byte
row VAR byte
num VAR byte
PIN VAR byte[4]
ADMIN VAR byte[4]
GREEN VAR PORTA.2
YELLOW VAR PORTA.1
BUZZER VAR PORTA.3
OPTION_REG.7 = 0
DATA 0,..............??????? I don't know how to write this part!!!

SETPIN:
SETPIN:
i = 0 WHILE i<4 PIN = 0 GOSUB KEYPAD LET PIN = num i = i + 1
WEND

CHKAMD:
WRITE 1, PIN
PAUSE 200
READ 0, ADMIN
PAUSE 200
IF PIN4 = ADMIN THEN
GREEN = 1
END
ELSE
GOTO SETPIN
ENDIF
KEYPAD:
PAUSE 50

NO_KEY:
TRISB = %01111000
PORTB = 0
IF ((PORTB >> 3)!= %1111)THEN GOTO NO_KEY
PAUSE 50

GOTKEY:
FOR col = 0 to 2
row = 0 TRISB = (dcd col)^%11111111
PORTB = 1
row = PORTB>>3
IF (row!= %1111)THEN CAL_NUM
NEXT col
GOTO GOTKEY

CAL_NUM:
YELLOW = 1
SOUND BUZZER,[100,10]
PAUSE 500
YELLOW = 0
num = (col*3) + (ncd (row^$F))
RETURN
Please tell me what changes do i have to make to this program.
Thanks a million!!!

Tim B
- 28th November 2003, 23:41
Here is a sample of code that I have written to scan a 4 x 4 keyboard just remove unwanted scans to reduce the no columns / rows

Pbp does not have clear so replace that with ??? = 0 also it does not have break so replace that with goto label (label would be just after the endif) Dec replace with let x = x - 1

It is quite a neat routine and debounces with out using pause, but if you want you can delete that section and use pause.

Have you looked at my password program here ...

http://users.picbasic.org/index.php?page=projects&category=1

Tim


DEVICE 16F628A

DIM KBRD_PORT AS PORTB
DIM KBRD_PORT_TRIS AS TRISB
DIM KBRD_PORT_COLUMNS AS %11110000 ' DEFINE THE COLUMN INPUTS
DIM KBRD_PORT_ROWS AS %00001111 ' DEFINE THE ROW INPUTS
DIM KBRD_ROWS AS 4 ' NUMBER OF ROWS IN PORT
DIM DEBOUNCE_CNT_VAL AS 4

DIM KBRD_TEMP AS BYTE ' TEMP VARS
DIM KBRD_TEMP2 AS BYTE ' /
DIM KEY AS BYTE ' KEY RESULT
DIM LAST_KEY ' KEY READ IN LAST SCAN
DIM KEY_FLAGS AS BYTE ' KEY SCAN GEN CONTROL FALGS
DIM DEBOUNCE_CNTR AS BYTE '

DIM KEY_PRESSED AS KEY_FLAGS.0 ' GENERAL CONTROL FLAGS
DIM NEW_KEY AS KEY_FLAGS.1

PORTB_PULLUPS = 1
KBRD_PORT_TRIS = KBRD_PORT_COLUMNS ' MAKE THE COLUMNS BITS INPUTS

GOTO START

KEYSCAN:
KBRD_PORT = KBRD_PORT_ROWS ^ KBRD_PORT_ROWS ' SEND ROW LINES LOW
KBRD_TEMP = KBRD_PORT & %11110000 ' READ ALL THE COLUMNS INPUTS
IF KBRD_TEMP <> $F0 THEN ' ONLY DO THE REST IF A KEY WAS PRESSED
KBRD_TEMP = KBRD_ROWS ' NO OF ROWS TO SCAN
KBRD_TEMP2 = %11111110 ' SET UP MASK
KEY_PRESSED = 0 ' CLEAR THE FLAG TO START WITH
CLEAR KEY
REPEAT
KBRD_PORT = KBRD_TEMP2 ' WRITE TO THE PORT TO SET THE ROW LOW
INC KEY
IF KBRD_PORT.4 = 0 THEN KEY_PRESSED = 1: BREAK ' CHECK COLUMN 1
INC KEY
IF KBRD_PORT.5 = 0 THEN KEY_PRESSED = 1: BREAK ' CHECK COLUMN 2
INC KEY
IF KBRD_PORT.6 = 0 THEN KEY_PRESSED = 1: BREAK ' CHECK COLUMN 3
INC KEY
IF KBRD_PORT.7 = 0 THEN KEY_PRESSED = 1: BREAK ' CHECK COLUMN 4
DEC KBRD_TEMP
KBRD_TEMP2 = KBRD_TEMP2 << 1 ' ROTATE THE MASK
SET KBRD_TEMP2.0 ' SET THE BOTTOM BIT
UNTIL KBRD_TEMP = 0 ' SCAN ALL THE ROWS
IF KEY_PRESSED = 1 THEN KEY_SCAN_DONE ' HAS A KEY BEEN PRESSED
ENDIF
CLEAR KEY ' IF WE GET TO HERE NO KEY HAS BEEN PRESSED
' SO MAKE IT READ 0
KEY_SCAN_DONE:
LAST_KEY = KEY
IF KEY = 0 THEN DEC DEBOUNCE_CNTR
IF DEBOUNCE_CNTR = 0 THEN
DEBOUNCE_CNTR = DEBOUNCE_CNT_VAL
NEW_KEY = TRUE
ELSE
IF KEY <> LAST_KEY THEN
DEBOUNCE_CNTR = DEBOUNCE_CNT_VAL
NEW_KEY = TRUE
ENDIF

RETURN

START:
CLS ' CLEAR THE LCD
WHILE 1 = 1
GOSUB KEYSCAN
PRINT AT 1,1 DEC KEY ' PRINT TO THE LCD
DELAYMS 10
WEND

Darrel Taylor
- 29th November 2003, 22:05
Hi pt3rg,

In case you still want to troubleshoot the original post.

I think the problem with the first column is due to the

PORTB = 1 in the GOTKEY routine.

Since an active keypress must pull the input low to register correctly. Holding a column high prevents it from doing so. Removing the statement should work better.

As for the EEPROM:

You are showing ADMIN as a four byte array. So you need to store each byte individually.

DATA @0, 1,2,3,4 will store the value in locations 0 thru 3

then to read it back:

for x = 0 to 3
Read x, ADMIN[x]
next x

Then you'll need to test each byte, against each keypress, for a password match.


HTH,
Darrel Taylor

pt3rg
- 1st December 2003, 17:51
Thanks a million, Tim and Darrel.

I managed to troubleshoot my original program and WOW!
There were more flaws than i thought, but now, thanks to Tim and Darrel, it's fully functioning!!! :D

Thanks again.

pt3rg

Darrel Taylor
- 2nd December 2003, 02:21
Sweat!! :)

Glad to hear it, and your welcome.

Darrel