View Full Version : Keypad unlock (as in garage door possibly)

- 9th March 2006, 16:25
'************************************************* ************
'* Name : garage door unlock *
'* Author : Fred *
'* Date : 07/12/2006 *
'* Version : 1.A.5 *
'* Notes : this code will unlock after the correct code *
'* : sequence. It will remember the code even if *
'* : power goes out by writing the unlock code to *
'* : EEPROM. It uses the standard 12 key - keypad *
'* : but can be easily modified to use any keypad. *
'* : There are a lot of LCD commands I used to *
'* : debug but they can be take out easily. If *
'* : someone improves this GREAT!! That's the idea *
'* : You enter the correct code then press * to *
'* : to unlock. # resets the sequence. You program *
'* : by grounding the PortA.2 pin then enter code *
'* : followed by * then unground pin. It makes a *
'* : relay for 1/2 second which connects to door *
'* : switch to open or close garage door when you *
'* : correct code number *
'************************************************* ************
'Pin 1 RA2 - Switch to progam code
'Pin 2 RA3 - Relay 1 output
'Pin 3 RA4 - Relay 2 output
'Pin 4 RA5/MCLR - Hard reset switch
'Pin 5 VSS - Grd
'Pin 6 RB0 - Row 1
'Pin 7 RB1 - Row 2
'Pin 8 RB2 - Row 3
'Pin 9 RB3 - Row 4
'Pin 10 RB4 - Col 1
'Pin 11 RB5 - Col 2
'Pin 12 RB6 - Col 3
'Pin 13 RB7 - LED output
'Pin 14 VDD - +5
'Pin 15 RA6 - Clock in
'Pin 16 RA7 - Clock
'Pin 17 RA0 - Serial data out
'Pin 18 RA1 - output to spkr connection
INCLUDE "modedefs.bas"

Col VAR BYTE ' Keypad column
Row VAR BYTE ' Keypad row
Key VAR BYTE ' Key value
SerPin VAR PortA.0 ' Serial output pin
KeyCode var byte
LED VAr PortB.7
Relay1 var PortA.3
Relay2 var PortA.4
CMCON = 7 ' PortA = digital I/O
VRCON = 0 ' Voltage reference disabled
OPTION_REG.7 = 0 ' Enable PORTB pull-ups
OldCode VAR BYTE[11]
NewCode VAR BYTE[10]
LoopCount VAR BYTE
ProgramSwitch var PortA.2
input programswitch

Setcode = 1
unlock = 1
Read 100,numdig 'Read number of digits of unlock code from memory
For loopcount = 1 to numdig ' Read unlock code from memory
Read loopcount,oldcode[loopcount]
Next loopcount

GOSUB getkey 'Get key from keypad
key = key - 1
LookUp key,["123456789*0#"],keycode ' Lookup table to decode key press

Newcode[setcode] = keycode

IF programswitch = 1 Then ' If this port high then program unlock code
high led

serout serpin,N9600,[254,1] 'keycode is the number
serout serpin,N9600,[254,128]
SEROUT serpin,N9600,["location is "]'Send key value out
serout serpin,N9600,[#setcode]
serout serpin,N9600,[254,192]
SEROUT serpin,N9600,["key is "]'Send key value out
serout serpin,N9600,[keycode]
IF keycode = "*" Then ' If key is a star end the program code
numdig = (setcode - 1)

serout serpin,N9600,[254,1] 'keycode is the number
serout serpin,N9600,[254,128]
SEROUT serpin,N9600,["numdig is "]'Send key value out
serout serpin,N9600,[#numdig]
pause 3000
Write 100,(numdig) 'setcode is number of digits of unlock number
for loopcount = 1 to Numdig
write loopcount,newcode[loopcount]
serout serpin,N9600,[254,1]
SEROUT serpin,N9600,[254,128] 'Send key value out
serout serpin,N9600,["loopcount is "]
SEROUT serpin,N9600,[#loopcount]'Send key value out
SEROUT serpin,N9600,[254,192] 'Send key value out
serout serpin,N9600,["new "]
SEROUT serpin,N9600,[(newcode[loopcount])]'Send key value out
oldcode[loopcount] = newcode[loopcount]
serout serpin,N9600,["-old "]
serout serpin,N9600,[(oldcode[loopcount])]
pause 3000
Setcode = 1
low led
GoTo loop
Setcode = setcode + 1
GoTo Loop

IF keycode = "#" Then ' Zero's the number of digits counter,
setcode = 1 'functions as a key reset
unlock = 1
serout serpin,N9600,[254,1]
goto loop

IF keycode = "*" Then ' If key is a star try to unlock door
For loopcount = 1 to Numdig
IF Newcode[loopcount] = oldcode[loopcount] Then
unlock = unlock + 1
IF unlock = Numdig Then ' If code matches unlock the door
high led ' LED shows unlock status, 1=LED on
high relay1 ' unlock relay on
serout serpin,N9600,[254,1]
serout serpin,N9600,[254,128]
serout serpin,N9600,["Door Unlocked"]
serout serpin,N9600,[254,192]
SEROUT serpin,N9600,[keycode]'Send key value out
Pause 500
For Loopcount = 1 to 10 ' Zero out keycode
Newcode[loopcount] = "E"
Next Loopcount
unlock = 1 ' Reset unlock
setcode = 1 ' Reset digit codes
low led ' Unlock LED off
low relay1 ' unlock relay off
goto loop
Setcode = 1
Unlock = 1
GoTo loop
Next Loopcount

if setcode > numdig then setcode = 1

Setcode = setcode + 1

gosub send
GoTo loop

serout serpin,N9600,[254,128]
SEROUT serpin,N9600,[#setcode]'Send key value out
SEROUT serpin,N9600,[254,192]'Send key value out
SEROUT serpin,N9600,[#Numdig]'Send key value out

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 * 3) + (NCD (col ^ $f))
'NOTE: for 12-key keypad, change to key = (row * 3) 16 key * 4
RETURN ' Subroutine over

- 10th March 2006, 13:00
You are very strong, really very well your program And me I am not able to make this program thank you

- 31st March 2006, 09:34
Hi there, I'm trying to use your code on a 16F648A, and getting unexpected results. I've read the spec sheet till I'm blue in the face and well, maybe I've missed something. But I thought I'd ask if you've done anything other than hook the outputs of the PIC to the Keypad and then hook into the inputs. ie, have you got any resistors or anything else inline? I seem to be getting some keys read sometimes with little or no rhyme or reason.

- 1st April 2006, 17:33
There is a pull up resistor from the MCLR to power and that is really the only necessary external "stuff" needed to play with it. The finished circuit has filter caps, xsistors, relays, etc. to make it functional. I used a standard 12 key keypad and the only thing I can think of is to make sure you have your rows, columns correct on the keypad. The keypad matrix code was picked up from the web, all I did was put in the stuff to lock, unlock the door. Start by removing all the extraneous code to the keypad and see if it returns the correct key sequence every time. You might need a debounce, although I have not found the need. This basic code has been running for several years with no issues at all. I did find that once I powered up the chip initially I had to do a chip clear by grounding the MCLR pin momentarily. I put a switch on the board to do that. I think it's because the power isn't real clean and I never bothered to put a cap and resistor on the chip to hold it down while the power stabilized. Other than that nothing comes to mind.

- 2nd April 2006, 03:50
Thanks very much for the response. I had a dodgey switch arrangement for the program switch and it was letting that pin float a bit so I changed it out and now it works great. Thanks for posting that code, very handy.

- 2nd April 2006, 04:26
Sorry for the double post but I thought I'd point out that if a would-be intruder applied say 12V or so to a few of the keys on the keypad the poor PIC would writhe in pain a bit then squirt some output to the garage door relay and Bobs your uncle... you're in. (assuming there are no measures taken to stop excess voltage being applied to any of the pins). I'm thinking I'll put a bunch of zeners inline.