PDA

View Full Version : Combinaton Gate access



Archangel
- 10th February 2007, 02:26
Hi Everyone,
I'm using mister_e's keypad.bas etc and trying to make a combination access for a driveway gate and not getting the results I am looking for. Does anyone see any glaring errors?
Thanks
JS


@MyConfig = _HS_OSC & _WDT_OFF & _PWRTE_ON & _LVP_OFF
@MyConfig = MyConfig & _BODEN_OFF
@ __config MyConfig
'@ __CONFIG _HS_OSC & _WDT_ON & _PWRTE_ON & _LVP_OFF & _CP_OFF
Define PIC16F877A
@ errorlevel -230
CMCON = 7
ADCON1 = 7
define OSC 20
TrisD = %00000000

DEFINE LCD_DREG PORTA
DEFINE LCD_DBIT 0
DEFINE LCD_RSREG PORTA
DEFINE LCD_RSBIT 5
DEFINE LCD_EREG PORTA
DEFINE LCD_EBIT 4
DEFINE LCD_BITS 4
DEFINE LCD_LINES 4

include "keypad.bas"

DEFINE KEYPAD_ROW 4 ' 4 ROW keypad
DEFINE KEYPAD_ROW_PORT PORTB ' ROW port = PORTB
DEFINE KEYPAD_ROW_BIT 4 ' ROW0 = PORTB.4
DEFINE KEYPAD_COL 4 ' 3 COL keypad
DEFINE KEYPAD_COL_PORT PORTB ' COL port = PORTB
DEFINE KEYPAD_COL_BIT 0 ' COL0 = PORTB.1
DEFINE KEYPAD_DEBOUNCEMS 50 ' debounce delay = 50 mSec
DEFINE SCAN_ONCE 1

OPTION_REG.7=0 ' Enable internal crap pull-up :D

PORTB = 0 '
TRISB = %11110000 '

ByteA var byte '
Combo1 var byte [4]
INTCON = %10001000 ' Enable global interrupt
' Enable interrupt on PORTB change
on interrupt goto KeypadInt
CLEAR

Init:
lcdout $FE,1,"Press any Key"
Start:
if ByteA then
If ByteA = 4 then ByteA = "A"
if ByteA = 5 then ByteA = 4
if ByteA = 6 then ByteA = 5
if ByteA = 7 then ByteA = 6
if ByteA = 8 then ByteA = "B"
if ByteA = 9 then ByteA = 7
if ByteA = 10 then ByteA = 8
if ByteA = 11 then ByteA = 9
if ByteA = 12 then ByteA = "C"
if ByteA = 13 then ByteA = "*"
if ByteA = 14 then ByteA = 0
if ByteA = 15 then ByteA = "#"
if ByteA = 16 then ByteA = "D"
LCDOUT $FE,1,"Key=",dec bytea
ByteA = 0
pause 1000
goto init
'else
if ByteA != 0 then gosub combo
else
endif
goto start


disable
KeypadINT:
@ READKEYPAD _ByteA
TRISB=%11110000
PORTB=0
INTCON.0=0
resume
enable
combo:
if ByteA = 7 then
combo1[0] = 7
gosub digit2
else
endif
return

digit2: if (ByteA = 8) and (combo1[0] = 7) then
combo1[1] = 8
gosub Digit3
else
endif
return
Digit3: if (ByteA = 65) and (combo1[1]=8 ) then
combo1[2] = 65
gosub Digit4
else
endif
return
Digit4: if (ByteA = 5) and (combo1[2] = 65) then
combo1[3] = 5
gosub Digit5
else
endif
return
Digit5: if (ByteA =68) and (combo1[3] = 5) then
combo1[4] = 68
goto Digit6
else
endif
return
Digit6: if combo1[4] = 68 then
lcdout "Gate Opening"
PortD.2 = 1
pause 30000
lcdout "Gate Closing"
pause 30000
ByteA = 0
Combo1 = 0
endif
goto start ' Combination 78A5D





end

skimask
- 10th February 2007, 03:39
I see simplifying it a bit... Whadaya think?
That and something looked wierd with your original, specifically with the if/else/endif's. You had a bunch of spots where you had a 'else' but didn't use it (or had a blank chunk in between the else and endif). I suspect those were messing something up.

@MyConfig = _HS_OSC & _WDT_OFF & _PWRTE_ON & _LVP_OFF
@MyConfig = MyConfig & _BODEN_OFF
@ __config MyConfig
'@ __CONFIG _HS_OSC & _WDT_ON & _PWRTE_ON & _LVP_OFF & _CP_OFF
Define PIC16F877A
@ errorlevel -230
define OSC 20
TrisD = 0:CMCON = 7 : ADCON1 = 7

DEFINE LCD_DREG PORTA
DEFINE LCD_DBIT 0
DEFINE LCD_RSREG PORTA
DEFINE LCD_RSBIT 5
DEFINE LCD_EREG PORTA
DEFINE LCD_EBIT 4
DEFINE LCD_BITS 4
DEFINE LCD_LINES 4

include "keypad.bas"

DEFINE KEYPAD_ROW 4 ' 4 ROW keypad
DEFINE KEYPAD_ROW_PORT PORTB ' ROW port = PORTB
DEFINE KEYPAD_ROW_BIT 4 ' ROW0 = PORTB.4
DEFINE KEYPAD_COL 4 ' 3 COL keypad
DEFINE KEYPAD_COL_PORT PORTB ' COL port = PORTB
DEFINE KEYPAD_COL_BIT 0 ' COL0 = PORTB.1
DEFINE KEYPAD_DEBOUNCEMS 50 ' debounce delay = 50 mSec
DEFINE SCAN_ONCE 1

OPTION_REG.7=0:PORTB = 0 : TRISB = $F0

ByteA var byte : Combo1 var byte [4]:combocount var byte
INTCON = $88
on interrupt goto KeypadInt
CLEAR

Init:
lcdout $FE,1,"Press any Key"
Start:
If ByteA = 4 then ByteA = "A"
if ByteA = 5 then ByteA = 4
if ByteA = 6 then ByteA = 5
if ByteA = 7 then ByteA = 6
if ByteA = 8 then ByteA = "B"
if ByteA = 9 then ByteA = 7
if ByteA = 10 then ByteA = 8
if ByteA = 11 then ByteA = 9
if ByteA = 12 then ByteA = "C"
if ByteA = 13 then ByteA = "*"
if ByteA = 14 then ByteA = 0
if ByteA = 15 then ByteA = "#"
if ByteA = 16 then ByteA = "D"
LCDOUT $FE,1,"Key=",dec bytea:ByteA = 0:pause 1000
if ByteA != 0 then gosub combo
goto start

disable
KeypadINT:
@ READKEYPAD _ByteA
TRISB=$F0:PORTB=0:INTCON.0=0
resume
enable

combo:
if ByteA = 7 and combocount = 0 then
combocount = 1
else
combocount = 0
endif
if ByteA = 8 and combocount = 1 then
combocount = 2
else
combocount = 0
endif
if ByteA = 65 and combocount = 2 then
combocount = 3
else
combocount = 0
endif
if ByteA = 5 and combocount = 3 then
combocount = 4
else
combocount = 0
endif
if ByteA =68 and combocount = 4 then
combocount = 5
else
combocount = 0
endif
if combocount = 5 then
lcdout "Gate Opening" : PortD.2 = 1 : pause 30000
lcdout "Gate Closing" : pause 30000 : ByteA = 0 : combocount = 0
endif
goto start ' Combination 78A5D
end




P.S. Now we all know the combo to your driveway gate! hhhmmmwwwaaaahaaahahahahahaha!!!!!! :)

bbarney
- 10th February 2007, 13:52
Joe what did you say your address was again? :)

Archangel
- 10th February 2007, 21:47
Joe what did you say your address was again? :)
1313 Mockingbird Lane, say Hello to Uncle Fester

bbarney
- 10th February 2007, 23:36
I know where that is I used to date cousin IT :)

Leonardo
- 11th February 2007, 01:15
This code doesn't work!.

Archangel
- 11th February 2007, 06:13
This code doesn't work!.

Yeah, that's why I posted it!
Thank You. I was sort of hoping someone would tell me why. All I got was jokes.

mister_e
- 11th February 2007, 09:29
tons of different way to do it. You could even set your secret code in an array, read the keypad x times, compare the result with the array.

i'll try something.. maybe this will put some lights...


'
' Hardware assignment
' ====================
'
' System LCD
' -----------
DEFINE LCD_DREG PORTD ' LCD data port
DEFINE LCD_DBIT 4 ' LCD data starting bit 0 or 4
DEFINE LCD_RSREG PORTD ' LCD register select port
DEFINE LCD_RSBIT 2 ' LCD register select bit
DEFINE LCD_EREG PORTD ' LCD enable port
DEFINE LCD_EBIT 3 ' LCD enable bit
DEFINE LCD_BITS 4 ' LCD bus size 4 or 8
DEFINE LCD_LINES 2 ' Number lines on LCD
DEFINE LCD_COMMANDUS 2000 ' Command delay time in us
DEFINE LCD_DATAUS 50 ' Data delay time in us

'
' 4X4 matrix Keypad
' -----------------
include "c:\PBP_PROG\Include_Routines\keypad.bas"
DEFINE KEYPAD_ROW 4 ' 4 ROW keypad
DEFINE KEYPAD_ROW_PORT PORTB ' ROW port = PORTB
DEFINE KEYPAD_ROW_BIT 4 ' ROW0 = PORTB.4
DEFINE KEYPAD_COL 4 ' 4 COL keypad
DEFINE KEYPAD_COL_PORT PORTB ' COL port = PORTB
DEFINE KEYPAD_COL_BIT 0 ' COL0 = PORTB.0
DEFINE KEYPAD_DEBOUNCEMS 100 ' debounce delay = 100 mSec

'
' Variables definition
' ===================
SecretCode var byte[5]
CounterA var byte
Match var byte

'
' Software/Hardware initialisation
' ================================
secretcode[0]=1
secretcode[1]=2
secretcode[2]=3
secretcode[3]=4
secretcode[4]=5

'
' Program start
' =============
Start:
match=0
lcdout $FE,1,"Enter the code"
for countera = 0 to 4
@ READKEYPAD _Key
if Key=secretcode[countera] then Match=Match+1
lcdout $FE,($C0+COUNTERA),"*"
next

if match=5 then
lcdout $FE,1,"Access Granted!"
else
lcdout $FE,1,"Access denied..."
endif

PAUSE 2000
goto start

to answer your original question... your code don't work because you don't keep track of your user entry. So it always stick to the first character => 7

and this...


If ByteA = 4 then ByteA = "A"
if ByteA = 5 then ByteA = 4
if ByteA = 6 then ByteA = 5
if ByteA = 7 then ByteA = 6
if ByteA = 8 then ByteA = "B"
if ByteA = 9 then ByteA = 7
if ByteA = 10 then ByteA = 8
if ByteA = 11 then ByteA = 9
if ByteA = 12 then ByteA = "C"
if ByteA = 13 then ByteA = "*"
if ByteA = 14 then ByteA = 0
if ByteA = 15 then ByteA = "#"
if ByteA = 16 then ByteA = "D"

could be replace by the single line bellow.


LOOKUP ByteA,[0,1,2,3,"A",4,5,6,"B",7,8,9,"C","*",0,"#","D"],ByteA


Or store the table in the EEPROM, then read from it..


DATA @1,1,2,3,"A",4,5,6,"B",7,8,9,"C","*",0,"#","D"
'
'
'
'
'
Read ByteA, ByteA

Darrel Taylor
- 11th February 2007, 12:09
Yup, there's Tons of different ways.

But first, why doesn't Joe's program work...


There's no way out of the Start: loop. It never makes it to combo:
There are too many nested gosubs. It'll overflow the stack before it gets a full combination entered. You only get 4 levels.
Spaghetti code like that needs Marinara, not Picante sauce. :)

So here's one of those other ways. It has 2 security levels, timeouts, and an easy to set Code in EEPROM.

@MyConfig = _HS_OSC & _WDT_OFF & _PWRTE_ON & _LVP_OFF
@MyConfig = MyConfig & _BODEN_OFF
@ __config MyConfig
'@ __CONFIG _HS_OSC & _WDT_ON & _PWRTE_ON & _LVP_OFF & _CP_OFF

CLEAR

;________________________User Configurable Settings___________________________
DEFINE HIGH_SECURITY 1 ; For HIGH_SECURITY, the user is required to enter
; the exact number of digits, Followed by the # sign
MaxTime CON 5000 ; Timeout if no keypress, in ms
Data @0, 5, "78A5D" ; Length of, and The Combination
; Since it's in EEPROM, it can be changed later.
;_________________________________________________ ____________________________


Define PIC16F877A
@ errorlevel -230
CMCON = 7
ADCON1 = 7
define OSC 20
TrisD = %00000000

DEFINE LCD_DREG PORTA
DEFINE LCD_DBIT 0
DEFINE LCD_RSREG PORTA
DEFINE LCD_RSBIT 5
DEFINE LCD_EREG PORTA
DEFINE LCD_EBIT 4
DEFINE LCD_BITS 4
DEFINE LCD_LINES 4

disable debug
include "keypad.bas"
enable debug

DEFINE KEYPAD_ROW 4 ' 4 ROW keypad
DEFINE KEYPAD_ROW_PORT PORTB ' ROW port = PORTB
DEFINE KEYPAD_ROW_BIT 4 ' ROW0 = PORTB.4
DEFINE KEYPAD_COL 4 ' 3 COL keypad
DEFINE KEYPAD_COL_PORT PORTB ' COL port = PORTB
DEFINE KEYPAD_COL_BIT 0 ' COL0 = PORTB.1
DEFINE KEYPAD_DEBOUNCEMS 50 ' debounce delay = 50 mSec
DEFINE SCAN_ONCE 1

ByteA var byte
ComboLength VAR BYTE
ComboPtr VAR BYTE
Timeout VAR WORD
Failed VAR BIT
ReStart VAR BIT

OPTION_REG.7=0 ' Enable the Excellent internal PORTB pull-ups :D
TRISB = %11110000 ' Set Keypad I/O
PORTB = 0 ' Set columns LOW
INTCON = %10001000 ' Enable global interrupt, and PORTB change

on interrupt goto KeypadInt ; ON INTERRUPT ???? :)

Init:
ReStart = 0
lcdout $FE,1
pause 500
Failed = 0
Read 0, ComboLength
lcdout $FE,1,"Press any Key"
Start:
pause 1
Timeout = Timeout - 1
if (ComboPtr > 0) and (Timeout = 0) then Gosub Reset
if ReStart then Init
goto Start

;_________________________________________________ ____________________________
disable
@ ifndef HIGH_SECURITY
@ #define HIGH_SECURITY 0 ; default to Low security
@ endif

KeypadINT:
@ READKEYPAD _ByteA ; Get the keypress
TRISB=%11110000 ; Reset I/O's
PORTB=0 ; Set all columns LOW
INTCON.0=0 ; Clear RBIF
Timeout = MaxTime ; Reset the Timeout
lookup ByteA,[0,"123A456B789C*0#D"],Key ; convert keypress
ComboPtr = ComboPtr + 1 ; point to next digit
@ if HIGH_SECURITY == 1
LCDOUT $FE, $C4 + ComboPtr, "*" ; print a Mask character
if Key = "*" then Reset
if Key = "#" then Finish
@ endif
if ComboPtr <= ComboLength then
Read ComboPtr, ByteA ; Get the digit from EEPROM
if Key = ByteA then ; is it the same ?
Read 0, ByteA ; Get the length of the combo
@ if HIGH_SECURITY == 0
LCDOUT $FE, $C4 + ComboPtr, "*" ; print a Mask character
if ComboPtr = ByteA then AccessGranted ; Done?, Grant Access
@ endif
else
@ if HIGH_SECURITY == 0
ComboPtr = 0 ; Wrong digit
goto AccessDenied ; terminate entry
@ else ; -HIGH_SECURITY-
Failed = 1 ; let them keep entering
@ endif ; makes it harder to figure
Endif ; the combination
endif
resume ; must end with # sign

AccessGranted:
ComboPtr = 0
lcdout $FE,1," Gate Opening"
PortD.2 = 1
pause 30000
lcdout $FE,1,$FE,$C0," Gate Closing"
pause 30000
ReStart = 1
resume

AccessDenied:
ComboPtr = 0
LCDOUT $FE, 1, " Access Denied"
; Zapp them with 5000v to the kaypad :)
pause 2000
ReStart = 1
resume

Reset:
ComboPtr = 0
LCDOUT $FE, 1, " Entry Reset"
pause 2000
ReStart = 1
resume

Finish:
if (Failed = 0) and (ComboPtr = ComboLength + 1) then
goto AccessGranted
else
goto AccessDenied
endif
enable

mister_e
- 11th February 2007, 12:33
Nice one Darrel!




http://www.mister-e.org/Pics/ROFL.gif on interrupt goto KeypadInt ; ON INTERRUPT ???? :eek:

Leonardo
- 12th February 2007, 03:21
Hello mister_e,
I magnify code it works very well but I have not been able to configure my keyboard correctly. Can help me?.
For the access I should oppress 1,2,3, A,6 and they don't correspond this way the keys.


I include the files in proteus.

Thank you


[QUOTE=mister_e;32450]tons of different way to do it. You could even set your secret code in an array, read the keypad x times, compare the result with the array.

i'll try something.. maybe this will put some lights...


'
' Hardware assignment
' ====================
'
' System LCD
' -----------
DEFINE LCD_DREG PORTD ' LCD data port
DEFINE LCD_DBIT 4 ' LCD data starting bit 0 or 4
DEFINE LCD_RSREG PORTD ' LCD register select port
DEFINE LCD_RSBIT 2 ' LCD register select bit
DEFINE LCD_EREG PORTD ' LCD enable port
DEFINE LCD_EBIT 3 ' LCD enable bit
DEFINE LCD_BITS 4 ' LCD bus size 4 or 8
DEFINE LCD_LINES 2 ' Number lines on LCD
DEFINE LCD_COMMANDUS 2000 ' Command delay time in us
DEFINE LCD_DATAUS 50 ' Data delay time in us

'
' 4X4 matrix Keypad
' -----------------
include "c:\PBP_PROG\Include_Routines\keypad.bas"
DEFINE KEYPAD_ROW 4 ' 4 ROW keypad
DEFINE KEYPAD_ROW_PORT PORTB ' ROW port = PORTB
DEFINE KEYPAD_ROW_BIT 4 ' ROW0 = PORTB.4
DEFINE KEYPAD_COL 4 ' 4 COL keypad
DEFINE KEYPAD_COL_PORT PORTB ' COL port = PORTB
DEFINE KEYPAD_COL_BIT 0 ' COL0 = PORTB.0
DEFINE KEYPAD_DEBOUNCEMS 100 ' debounce delay = 100 mSec

'
' Variables definition
' ===================
SecretCode var byte[5]
CounterA var byte
Match var byte

'
' Software/Hardware initialisation
' ================================
secretcode[0]=1
secretcode[1]=2
secretcode[2]=3
secretcode[3]=4
secretcode[4]=5

'
' Program start
' =============
Start:
match=0
lcdout $FE,1,"Enter the code"
for countera = 0 to 4
@ READKEYPAD _Key
if Key=secretcode[countera] then Match=Match+1
lcdout $FE,($C0+COUNTERA),"*"
next

if match=5 then
lcdout $FE,1,"Access Granted!"
else
lcdout $FE,1,"Access denied..."
endif

PAUSE 2000
goto start

Archangel
- 12th February 2007, 07:21
could be replace by the single line bellow.


LOOKUP ByteA,[0,1,2,3,"A",4,5,6,"B",7,8,9,"C","*",0,"#","D"],ByteA


Or store the table in the EEPROM, then read from it..


DATA @1,1,2,3,"A",4,5,6,"B",7,8,9,"C","*",0,"#","D"
'
'
'
'
'
Read ByteA, ByteA
ALLRIGHTY THEN,
Hi Steve, Darrel and all,
For starters . . . Lookup table listed will do the kepad remapping of my long and convouluted code? Cool, I must learn more about this, also how to set up eprom, as I have never figured that out.
Darrel, you said my code never went to gosub, . . . the if bytea != 0 then gosub combo, will not do it?
before you and Steve posted, but after skimask did I wrote the following


@MyConfig = _HS_OSC & _WDT_OFF & _PWRTE_ON & _LVP_OFF
@MyConfig = MyConfig & _BODEN_OFF
@ __config MyConfig
'@ __CONFIG _HS_OSC & _WDT_ON & _PWRTE_ON & _LVP_OFF & _CP_OFF
Define PIC16F877A
@ errorlevel -230
CMCON = 7
ADCON1 = 7
define OSC 20
TrisD = %00000000

DEFINE LCD_DREG PORTA
DEFINE LCD_DBIT 0
DEFINE LCD_RSREG PORTA
DEFINE LCD_RSBIT 5
DEFINE LCD_EREG PORTA
DEFINE LCD_EBIT 4
DEFINE LCD_BITS 4
DEFINE LCD_LINES 4

include "keypad.bas"
pause 1000
lcdout 254,1
lcdout 254,128,"PIC Self Test"
pause 1000

DEFINE KEYPAD_ROW 4 ' 4 ROW keypad
DEFINE KEYPAD_ROW_PORT PORTB ' ROW port = PORTB
DEFINE KEYPAD_ROW_BIT 4 ' ROW0 = PORTB.4
DEFINE KEYPAD_COL 4 ' 3 COL keypad
DEFINE KEYPAD_COL_PORT PORTB ' COL port = PORTB
DEFINE KEYPAD_COL_BIT 0 ' COL0 = PORTB.1
DEFINE KEYPAD_DEBOUNCEMS 50 ' debounce delay = 50 mSec
DEFINE SCAN_ONCE 1

OPTION_REG.7 = 0 ' Enable internal crap pull-up :D

PORTB = 0 '
TRISB = %11110000 '
Flags = 0
ByteA var byte '
Combocount var byte
INTCON = %10001000 ' Enable global interrupt
' Enable interrupt on PORTB change
on interrupt goto KeypadInt
CLEAR
lcdout 254,128," Initializing"
LCDOUT 254,192,"System"
pause 1000
Portd.2 = 0
combocount = 0

Init:
lcdout $FE,1
LCDOUT 254,128,"AUTHORIZATION"
LCDOUT 254,192,"REQUIRED TO OPEN"
LCDOUT 254,153,"THIS GATE"
LCDOUT 254,212,"KEY ENTRY CODE"
disable
KeypadINT:
@ READKEYPAD _ByteA
TRISB=%11110000
PORTB=0
INTCON.0=0
resume
enable


Start:
if ByteA then
If ByteA = 4 then ByteA = "A"
if ByteA = 5 then ByteA = 4
if ByteA = 6 then ByteA = 5
if ByteA = 7 then ByteA = 6
if ByteA = 8 then ByteA = "B"
if ByteA = 9 then ByteA = 7
if ByteA = 10 then ByteA = 8
if ByteA = 11 then ByteA = 9
if ByteA = 12 then ByteA = "C"
if ByteA = 13 then ByteA = "*"
if ByteA = 14 then ByteA = 0
if ByteA = 15 then ByteA = "#"
if ByteA = 16 then ByteA = "D"
if ByteA != 0 then gosub combo

ByteA = 0
pause 1000
goto init
'else

else
endif
goto start




combo:
LCDOUT $FE,1,"Key=",dec ByteA
if ((ByteA = 7) and (combocount = 0)) then
combocount = %00000001
pause 1000
else
combocount = 0
endif
if ((ByteA = 8) and (combocount = %00000001)) then
combocount = %00000011
pause 1000
else
combocount = 0
endif
if ((ByteA = 65) and (combocount = %00000011)) then
combocount = %00000111
pause 1000
else
combocount = 0
endif
if ((ByteA = 5) and (combocount = %00000111)) then
combocount = %000011111
pause 1000
else
combocount = 0
endif
if ((ByteA =68) and (combocount = %00001111)) then
combocount = %00011111
pause 1000
else
combocount = 0
endif
if combocount = %00011111 then PortD.2 = 1
lcdout 254,1
pause 10
lcdout 254,128,"Gate Opening" : pause 30000
lcdout 254,1
pause 10
lcdout 254,192,"Gate Closing" : pause 30000 : ByteA = 0 : combocount = 0
lcdout 254,1
PortD.2 = 0
'endif
goto init ' Combination 78A5D


end

and it opened the gate with the push of any button, well almost, really it lied and said the gate was opening, and I have not had time to redress this issue.
I even played with another asm. code file emailed to me, that was fun learning how to use mpasm in windows, and editing the asm file without actual Knowledge of assembly, but I got it to compile and, you guessed it, it didn't work as expected either, just outputted a few strings all over the lcd. So here i am looking at the examples you and Steve have provided, thinking I will figure this out, likely not today:)
JS
edit1:Well I haven't learned all the lessons here, but the code works really well, Thanks!
edit2:Wow now I see how eprom works! Thanks again Darrel!
edit3: Thanks Steve for lookup table, now that makes sense too!
Just modified code to work as alarm console too, cool!

Darrel Taylor
- 12th February 2007, 11:57
Darrel, you said my code never went to gosub, . . . the if bytea != 0 then gosub combo, will not do it?

In the first post, that IF statement was After a GOTO statement. So it never gets executed. I see you've moved it in the latest version. But the rest ruined it.

I had actually addressed this problem earlier, then realized I was answering skimasks post instead of the original one. I guess I get to say it again.

First off, when you see a whole buch of IF statements one after the other, each one trying to catch a certain set of circumstances, it's probably the wrong way to do it. And this one is a prime example.

Let's say that the first keypress is a seven. The first IF statement works fine.
if ((ByteA = 7) and (combocount = 0)) then
combocount = %00000001
pause 1000
else
combocount = 0
endif
It recognizes the first digit of the combination, and sets combocount to 1

Then it continues on to the next IF statement...
if ((ByteA = 8) and (combocount = %00000001)) then
combocount = %00000011
pause 1000
else
combocount = 0
endif
At this point ByteA does not equal 8 (it's still 7), so it goes to the ELSE clause where it zero's combocount and starts everything from scratch again. It'll never recognize more than 1 digit.

Then after all the IF's are done, there's nothing to stop it from opening the gate, even though it only received 1 keypress.

But from the sound of it, it did exactly what you told it to.
<br>

Leonardo
- 12th February 2007, 12:17
Hello Joe,

It already works your I code?.

mister_e
- 12th February 2007, 17:03
@ Joe,

in your previous example, you should move your ISR or jump over



Init:
lcdout $FE,1
LCDOUT 254,128,"AUTHORIZATION"
LCDOUT 254,192,"REQUIRED TO OPEN"
LCDOUT 254,153,"THIS GATE"
LCDOUT 254,212,"KEY ENTRY CODE"

' ----> goto start:
disable
KeypadINT:
@ READKEYPAD _ByteA
TRISB=%11110000
PORTB=0
INTCON.0=0
resume
enable
Start:
What happen here is that it meet a RESUME, which do something close to a RETURN. Having nothing is the stack, it jump somewhere you don't know and execute the code at the top again and again... and again...

mister_e
- 12th February 2007, 17:05
Leonardo, sorry i don't have Proteus, will be faster if you tell me wich PIC and how your keypad is attach to it.

Archangel
- 12th February 2007, 20:13
@ Joe,

in your previous example, you should move your ISR or jump over
[code]


Dough! . . . thanks Steve that does make sense. This project has been hugely successful, not only do I have working code now but more importantly I have learned enough to keep me busy understanding what I learned for weeks!
THANKS GUYS !

mister_e
- 12th February 2007, 20:31
sweet!

Pump up the volume... ;)
<embed src="http://www.mister-e.org/Wav/yehaw.wav" autostart=false loop=false>

Archangel
- 13th February 2007, 00:41
Then it continues on to the next IF statement...
if ((ByteA = 8) and (combocount = %00000001)) then
combocount = %00000011
pause 1000
else
combocount = 0
endif
At this point<b> ByteA does not equal 8 (it's still 7), so it goes to the ELSE clause where it zero's combocount and starts everything from scratch again.</b> It'll never recognize more than 1 digit.
<b>
Then after all the IF's are done, there's nothing to stop it from opening the gate, even though it only received 1 keypress.</b>

But from the sound of it, it did exactly what you told it to.
<br> Is that because it has not gone back to the scan routine? Should I have used goto and resume or just put return after each if...then statement? I ask this <b>not </b>ignoring your statement I should not have done it this way in the first place.<br>
<b> Could you explain in more detail as to why? How does combocount get to the correct status to open the gate?</b>
<b>I really appreciate it Darrel.</b>
JS

Darrel Taylor
- 13th February 2007, 06:37
Is that because it has not gone back to the scan routine? Should I have used goto and resume or just put return after each if...then statement?

None of the above.
It's because it's the Wrong Logic for the job.

With an IF ELSE ENDIF, there are only 2 possibilities. True or False.
And that result is based entirely on 1 expression ... (ByteA = 7) and (combocount=0)

So essentially, you're asking it if the Whole combination is correct, by looking at just one keypress.

Then by stacking up 5 IF ELSE ENDIF's together, since they can't ALL be true at the same time, there will always be 4 of them saying the combination is Wrong.

Much like in real life, decisions aren't always as easy as True or False.
Usually, you'll have to consider several different things Before making a decision.
And those "things" may happen at different times, so you may not be able to make a decision until more information is available.

So instead of just the True or False, Black or White. Here's the answer.
You also need to be able to say "I don't know yet".

This is where just IF THEN is more useful.
Instead of only the 2 possibilities, IF THEN has Infinite possibilities.
Granted, It's either TRUE, or it's NOT, but by not taking action when it's not true, it's the same as saying "I don't know".

So now you can stack those up if you want, because they won't be interfering with each other by making their own decisions independently.
They only act on what they KNOW to be TRUE.

Here's what I mean...Still not the way I would do it, but for the sake of argument...
combo:
IF (combocount = 0) and (ByteA = 7) then GoodKey
IF (combocount = 1) and (ByteA = 8) then GoodKey
IF (combocount = 2) and (ByteA = "A") then GoodKey
IF (combocount = 3) and (ByteA = 5) then GoodKey
IF (combocount = 4) and (ByteA = "D") then GoodKey
combocount = 0 ; invalid keypress
return

GoodKey:
combocount = combocount + 1
if combocount = 5 then GrantAccess
return

Archangel
- 13th February 2007, 07:46
None of the above.
It's because it's the Wrong Logic for the job.

With an IF ELSE ENDIF, there are only 2 possibilities. True or False.
And that result is based entirely on 1 expression ... (ByteA = 7) and (combocount=0)

So essentially, you're asking it if the Whole combination is correct, by looking at just one keypress.

Then by stacking up 5 IF ELSE ENDIF's together, since they can't ALL be true at the same time, there will always be 4 of them saying the combination is Wrong.

Much like in real life, decisions aren't always as easy as True or False.
Usually, you'll have to consider several different things Before making a decision.
And those "things" may happen at different times, so you may not be able to make a decision until more information is available.

So instead of just the True or False, Black or White. Here's the answer.
You also need to be able to say "I don't know yet".

This is where just IF THEN is more useful.
Instead of only the 2 possibilities, IF THEN has Infinite possibilities.
Granted, It's either TRUE, or it's NOT, but by not taking action when it's not true, it's the same as saying "I don't know".

So now you can stack those up if you want, because they won't be interfering with each other by making their own decisions independently.
They only act on what they KNOW to be TRUE.

Here's what I mean...Still not the way I would do it, but for the sake of argument...
combo:
IF (combocount = 0) and (ByteA = 7) then GoodKey
IF (combocount = 1) and (ByteA = 8) then GoodKey
IF (combocount = 2) and (ByteA = "A") then GoodKey
IF (combocount = 3) and (ByteA = 5) then GoodKey
IF (combocount = 4) and (ByteA = "D") then GoodKey
combocount = 0 ; invalid keypress
return

GoodKey:
combocount = combocount + 1
if combocount = 5 then GrantAccess
return

I Get it, Thanks Darrel, then If you were inclined to code that way, would this be a place for select case? It seems as though the THEN Goodkey scenerio would make the combination work if out of sequence? Or would the loop cancel before combocount reaches 5 ? Oh your code works SWEET! Thanks Again.
Joe

Darrel Taylor
- 13th February 2007, 08:32
would this be a place for select case?
You could, but it just uses more code space. It's pretty much a Select Case the way the last example is shown. But here's a Select Case version...
combo:
Select CASE combocount
Case 0 : if ByteA = 7 then GoodKey
Case 1 : if ByteA = 8 then GoodKey
Case 2 : if ByteA = "A" then GoodKey
Case 3 : if ByteA = 5 then GoodKey
Case 4 : if ByteA = "D" then GoodKey
END SELECT
combocount = 0
return

GoodKey:
combocount = combocount + 1
if combocount = 5 then GrantAccess
return

Or, just to keep things nice and confusing, you could also do this...
Combo:
Lookup combocount,[7,8,"A",5,"D"], NextDigit
if ByteA = NextDigit then
combocount = combocount + 1
if combocount = 5 then GrantAccess
else
combocount = 0
endif
return


It seems as though the THEN Goodkey scenerio would make the combination work if out of sequence?Nope, that can't happen. You should run the program in MCSP debugger and watch what happens. After watching debuggers for awhile, you'll be able to see it in your mind, and programming will go a lot smoother. And eventually, you won't even need the debugger anymore, or the PIC. It'll run inside your head.


Oh your code works SWEET! Thanks Again.
No Problemo!

Leonardo
- 13th February 2007, 15:00
Hello to all,

I have followed east subject and it seems to me excellent, my english is not very good but treatment for understanding what you say.

This it is a interesting project, I am working to record the data in eeprom, when it has ready the code send.

Leonardo
- 13th February 2007, 16:12
It works of this form?




@MyConfig = _HS_OSC & _WDT_OFF & _PWRTE_ON & _LVP_OFF
@MyConfig = MyConfig & _BODEN_OFF
@ __config MyConfig
'@ __CONFIG _HS_OSC & _WDT_ON & _PWRTE_ON & _LVP_OFF & _CP_OFF
Define PIC16F877A
@ errorlevel -230
CMCON = 7
ADCON1 = 7
define OSC 20
TrisD = %00000000

DEFINE LCD_DREG PORTA
DEFINE LCD_DBIT 0
DEFINE LCD_RSREG PORTA
DEFINE LCD_RSBIT 5
DEFINE LCD_EREG PORTA
DEFINE LCD_EBIT 4
DEFINE LCD_BITS 4
DEFINE LCD_LINES 4

include "keypad.bas"
pause 1000
lcdout 254,1
lcdout 254,128,"PIC Self Test"
pause 1000

DEFINE KEYPAD_ROW 4 ' 4 ROW keypad
DEFINE KEYPAD_ROW_PORT PORTB ' ROW port = PORTB
DEFINE KEYPAD_ROW_BIT 4 ' ROW0 = PORTB.4
DEFINE KEYPAD_COL 4 ' 3 COL keypad
DEFINE KEYPAD_COL_PORT PORTB ' COL port = PORTB
DEFINE KEYPAD_COL_BIT 0 ' COL0 = PORTB.1
DEFINE KEYPAD_DEBOUNCEMS 50 ' debounce delay = 50 mSec
DEFINE SCAN_ONCE 1

OPTION_REG.7 = 0 ' Enable internal crap pull-up :D

PORTB = 0 '
TRISB = %11110000 '
Flags = 0
ByteA var byte '
Combocount var byte
INTCON = %10001000 ' Enable global interrupt
' Enable interrupt on PORTB change
on interrupt goto KeypadInt
CLEAR

Portd.2 = 0
combocount = 0

Init:
lcdout $FE,1,"Press any Key"
disable
KeypadINT:
@ READKEYPAD _ByteA
TRISB=%11110000
PORTB=0
INTCON.0=0
resume
enable


Start:
if ByteA then
If ByteA = 4 then ByteA = "A"
if ByteA = 5 then ByteA = 4
if ByteA = 6 then ByteA = 5
if ByteA = 7 then ByteA = 6
if ByteA = 8 then ByteA = "B"
if ByteA = 9 then ByteA = 7
if ByteA = 10 then ByteA = 8
if ByteA = 11 then ByteA = 9
if ByteA = 12 then ByteA = "C"
if ByteA = 13 then ByteA = "*"
if ByteA = 14 then ByteA = 0
if ByteA = 15 then ByteA = "#"
if ByteA = 16 then ByteA = "D"
if ByteA != 0 then gosub combo

ByteA = 0
pause 1000
goto init
'else

else
endif
goto start

combo:
IF (combocount = 0) and (ByteA = 7) then GoodKey
IF (combocount = 1) and (ByteA = 8) then GoodKey
IF (combocount = 2) and (ByteA = "A") then GoodKey
IF (combocount = 3) and (ByteA = 5) then GoodKey
IF (combocount = 4) and (ByteA = "D") then GoodKey
combocount = 0 ; invalid keypress
return

GoodKey:
combocount = combocount + 1
if combocount = 5 then GrantAccess
return
goto init ' Combination 78A5D


GrantAccess:
hight portd.2
pause 1000
low portd.2
pause 1000

ByteA = 0
Combo1 = 0


end

Archangel
- 13th February 2007, 22:33
You should run the program in MCSP debugger and watch what happens. After watching debuggers for awhile, you'll be able to see it in your mind, and programming will go a lot smoother. And eventually, you won't even need the debugger anymore, or the PIC. It'll run inside your head.


I will have to make that purchase, as I have only the freebie version which was included with PBP, as you recommend it, it must be worthwhile.
Do you relize the power of this project? I am using it to operate the alarm on my mother's garage, another user here, for whom this was all about is using it for his gate, and it occured to me it is a useful tool to secure the table saw, bandsaw etc . . . from the children, or even adults! So since I do not have an address to send you some beer, i give you this, the knowledge that your efforts may save some little fingers.
JS

Archangel
- 13th February 2007, 22:36
It works of this form?




@MyConfig = _HS_OSC & _WDT_OFF & _PWRTE_ON & _LVP_OFF
@MyConfig = MyConfig & _BODEN_OFF
@ __config MyConfig
'@ __CONFIG _HS_OSC & _WDT_ON & _PWRTE_ON & _LVP_OFF & _CP_OFF
Define PIC16F877A
@ errorlevel -230
CMCON = 7
ADCON1 = 7
define OSC 20
TrisD = %00000000

DEFINE LCD_DREG PORTA
DEFINE LCD_DBIT 0
DEFINE LCD_RSREG PORTA
DEFINE LCD_RSBIT 5
DEFINE LCD_EREG PORTA
DEFINE LCD_EBIT 4
DEFINE LCD_BITS 4
DEFINE LCD_LINES 4

include "keypad.bas"
pause 1000
lcdout 254,1
lcdout 254,128,"PIC Self Test"
pause 1000

DEFINE KEYPAD_ROW 4 ' 4 ROW keypad
DEFINE KEYPAD_ROW_PORT PORTB ' ROW port = PORTB
DEFINE KEYPAD_ROW_BIT 4 ' ROW0 = PORTB.4
DEFINE KEYPAD_COL 4 ' 3 COL keypad
DEFINE KEYPAD_COL_PORT PORTB ' COL port = PORTB
DEFINE KEYPAD_COL_BIT 0 ' COL0 = PORTB.1
DEFINE KEYPAD_DEBOUNCEMS 50 ' debounce delay = 50 mSec
DEFINE SCAN_ONCE 1

OPTION_REG.7 = 0 ' Enable internal crap pull-up :D

PORTB = 0 '
TRISB = %11110000 '
Flags = 0
ByteA var byte '
Combocount var byte
INTCON = %10001000 ' Enable global interrupt
' Enable interrupt on PORTB change
on interrupt goto KeypadInt
CLEAR

Portd.2 = 0
combocount = 0

Init:
lcdout $FE,1,"Press any Key"
disable
KeypadINT:
@ READKEYPAD _ByteA
TRISB=%11110000
PORTB=0
INTCON.0=0
resume
enable


Start:
if ByteA then
If ByteA = 4 then ByteA = "A"
if ByteA = 5 then ByteA = 4
if ByteA = 6 then ByteA = 5
if ByteA = 7 then ByteA = 6
if ByteA = 8 then ByteA = "B"
if ByteA = 9 then ByteA = 7
if ByteA = 10 then ByteA = 8
if ByteA = 11 then ByteA = 9
if ByteA = 12 then ByteA = "C"
if ByteA = 13 then ByteA = "*"
if ByteA = 14 then ByteA = 0
if ByteA = 15 then ByteA = "#"
if ByteA = 16 then ByteA = "D"
if ByteA != 0 then gosub combo

ByteA = 0
pause 1000
goto init
'else

else
endif
goto start

combo:
IF (combocount = 0) and (ByteA = 7) then GoodKey
IF (combocount = 1) and (ByteA = 8) then GoodKey
IF (combocount = 2) and (ByteA = "A") then GoodKey
IF (combocount = 3) and (ByteA = 5) then GoodKey
IF (combocount = 4) and (ByteA = "D") then GoodKey
combocount = 0 ; invalid keypress
return

GoodKey:
combocount = combocount + 1
if combocount = 5 then GrantAccess
return
goto init ' Combination 78A5D


GrantAccess:
hight portd.2
pause 1000
low portd.2
pause 1000

ByteA = 0
Combo1 = 0


end

No Leonardo,
Use the code Darrel posted in post #9 above, or the version of it, I sent you.
JS

Archangel
- 13th February 2007, 22:41
As this is my first venture into eprom, and I understand how to change the value and number of digits prior to compiling, my question is this: once the chip is programmed, is the eprom value fixed, or can it be changed?

skimask
- 13th February 2007, 23:27
As this is my first venture into eprom, and I understand how to change the value and number of digits prior to compiling, my question is this: once the chip is programmed, is the eprom value fixed, or can it be changed?

Do you mean the on chip eeprom (which would be easier to use and is documented in the manual and is the method I'd use) or actual program flash (which would take a bit more code and would be harder)?

Archangel
- 13th February 2007, 23:45
Do you mean the on chip eeprom (which would be easier to use and is documented in the manual and is the method I'd use) or actual program flash (which would take a bit more code and would be harder)?RTFMRTFMRTFM
RTFMRTFMRTFMRTFMRTFMRTFMRTFMRTFMRTFMRTFM
RTFMRTFMRTFMRTFMRTFMRTFMRTFMRTFMRTFMRTFM
RTFMRTFMRTFMRTFMRTFMRTFMRTFM . . .Darn it skimask, I got some records that do that:)
I'm goin' to take that as a yes, use the write command. What
I think I am trying to do is change the combination on a chip
that is already programmed with this program. SO to clarify
my question, how the heck would I do that? Would it require
another loop or a serin write, Black Cat bones?

skimask
- 13th February 2007, 23:50
RTFMRTFMRTFM
RTFMRTFMRTFMRTFMRTFMRTFMRTFMRTFMRTFMRTFM
RTFMRTFMRTFMRTFMRTFMRTFMRTFMRTFMRTFMRTFM
RTFMRTFMRTFMRTFMRTFMRTFMRTFM . . .Darn it skimask, I got some records that do that:)
I'm goin' to take that as a yes, use the write command. What
I think I am trying to do is change the combination on a chip
that is already programmed with this program. SO to clarify
my question, how the heck would I do that? Would it require
another loop or a serin write, Black Cat bones?

No, no, no, I didn't mean for you to RTFM...this time I was only pointing it out, making sure.

I think I would set it up with a 'stock' combo when you program it set up in eeprom, say 12345 (that's amazing, I've got the same combination on my luggage!)...
Then, there's one sequence of numbers that only you know and will never tell anybody (call it a 'back door')...say, 1234567890.. If you get that sequence, the system knows that the next 5 numbers input will be the new combination and you have to enter them twice. Then save those new 5 numbers in the eeprom (read, write), and BAM the combo is changed.

Archangel
- 14th February 2007, 00:00
No, no, no, I didn't mean for you to RTFM...this time I was only pointing it out, making sure.

I think I would set it up with a 'stock' combo when you program it set up in eeprom, say 12345 (that's amazing, I've got the same combination on my luggage!)...
Then, there's one sequence of numbers that only you know and will never tell anybody (call it a 'back door')...say, 1234567890.. If you get that sequence, the system knows that the next 5 numbers input will be the new combination and you have to enter them twice. Then save those new 5 numbers in the eeprom (read, write), and BAM the combo is changed.
Clever Idea, backdoor . . . like in WAR GAMES . . and I bet you thought I was going to make some jokes :), That's going to be too much brain damage for now, tomorrow when I'm fresh, I will throw some spaghetti on the stove, and see what cooks out of it :)
Maybe if I am lucky sayzer or mister_e will send me some coffee :)
Thanks
JS

skimask
- 14th February 2007, 00:06
Clever Idea, backdoor . . . like in WAR GAMES . . and I bet you thought I was going to make some jokes :), That's going to be too much brain damage for now, tomorrow when I'm fresh, I will throw some spaghetti on the stove, and see what cooks out of it :)
Thanks
JS

Yep, that's what I was talking about...but not nearly as vocal (Shall we play a game?)
But I just had another thought or eight...
You could keep all the code you've got and just add an extra couple of flags so you could go thru the loop an extra time or two. If you go thru the loop once and get the 1st half of the back door (12345), you set the flag. Then the next number is a 6. Since the flag is set, you start looking for the 2nd half of the back door, etc.etc.etc. Or just write a whole seperate block of code to handle it.
Or maybe even have another 5 digit code that has to be set while the gate is open. Then the gate stays open while you change the code. That way if you screw it up, at least the gate is open. Or maybe during that time, you forget about the keypad read code and manually scan the keypad for a multiple keypress (say 1-2-3-4 all at the same time)....
Lots of options...

Archangel
- 14th February 2007, 00:15
Lots of options...
Yep, lots of options . . most of them are still above my pay grade, metephoricly speaking. I'll slog along and throw out some snippets as I do for comment or correction. I have learned a great deal from this thread, I hope lots of newbies read and understand what's in it, not just siphon the code. I think Darrel set this code up partially to do that as there is mention of High Security and Low security in the setup. Anywho, I'm getting some ideas, in my thick noggin' and I better go write them down!
JS

Archangel
- 14th February 2007, 09:20
This is going nowhere, I know you would use a statement like


write 0,newcode
or
write 0,ByteA

I cannot figure out how to make this program look beyond it's
original function to change eprom settings.
What was the meaning of HIGH_SECURITY 1 or 0 and if default is low security I do not see it run there :( I guess I really do not understand when the keypad is lookin at keypress and when not (if ever not) I thought at first to copy code for high security=1 and change to 0 examining added combo to eprom,
DATA 8,5,"12345" no avail. Changed in those lined data 0 to data 8
Is there a way to alter eprom from keypad?
very humbling experience here, and asm code, Black Magic?

Darrel Taylor
- 14th February 2007, 10:29
What was the meaning of HIGH_SECURITY 1 or 0

With Low security, if you press the wrong key, it immediately terminates entry and shows "Access Denied".
This is only good for "keeping the honest people out". Because for a 5 digit code, it would take a maximum of 80 keypresses to figure out the code. Or, if you're lucky, only 5.

High Security forces you to enter the exact number of digits followed by the # sign. This gives a maximum of 1,048,576 keypresses to guarantee finding the code. But with a 2 second delay after each failed attempt, it could take up to 582 days to try them all.

There really should be another level between those two. This mode would allow it to receive a string of keypresses (without showing an error), and if anywhere along the way the 5 digits are pressed in the right combination then access is granted. This is more like the way a building alarm pad works. It gives much better protection than the Low level, but if you forget the password, there's no way to figure it out.

;----

Personally, I don't like the "BackDoor" approach. That kind of thinking is for hackers and thieves. And if someone finds out about it, you can be sure it will be used against you. And if other people have this device, you can get blamed for anything that happens, whether it was your fault or not. But if it's just a one-off for you're own gate. Hey, go for it.

In my opinion, you should know the current code to be able to set a new code. Which means that once you've entered the correct password, you have a certain time period to enter another code, I would probably make it 3 stars. If that code is entered in time, it branches to another routine that allows you to enter the New Code.

Obviously, if you forget the code, the only way to reset it is to reprogram the chip. For security, That's a good thing.

Don't try to add more pasta by stitching things in with the existing keypad routine. Create a separate routine that handles entering the new code, and branch to it at the appropriate time. There's only so much marinara sauce in the world. And I want some of it for my dinner.

;----

Back to the EEPROM.

Location 0 is where the length of the Code is stored. The actual Code is stored from location 1 on.

Start at location 1, and store each keypress in successive locations. After they've finished entering the code (with a # sign), store the number of digits they entered in location 0.
<br>

Leonardo
- 14th February 2007, 12:30
Hello,

That "@" does this symbol in the code @ if HIGH_SECURITY == 1

They can explain to me?.

Darrel Taylor
- 14th February 2007, 21:54
The @ symbol allows you to enter a 1-line assembly language statement.
<br>

Archangel
- 14th February 2007, 22:47
There really should be another level between those two. This mode would allow it to receive a string of keypresses (without showing an error), and if anywhere along the way the 5 digits are pressed in the right combination then access is granted. This is more like the way a building alarm pad works. It gives much better protection than the Low level, but if you forget the password, there's no way to figure it out.
I have absolutely no idea how to do that, because I do not understand how the code works now.Why even have a low security setting? What i am looking for is not a back door, rather a master password which enters only a setup loop to program the eprom. I figured out how to vary the # of digits and alter password at compile, how would I set a master password? What actually tracks the digits entered, does it continue to track them while executing a gosub? can I call them from a running subroutine to exit into a setup loop? <br> Ok getting Idea now, a little chocolate is brain food:) , @ READKEYPAD _ByteA, is how program knows to check keypad. Store in ByteA



Personally, I don't like the "BackDoor" approach. That kind of thinking is for hackers and thieves. And if someone finds out about it, you can be sure it will be used against you. And if other people have this device, you can get blamed for anything that happens, whether it was your fault or not. But if it's just a one-off for you're own gate. Hey, go for it.

It in not something I want to MFG, probably patent issues there, but I want a few for my own uses.

In my opinion, you should know the current code to be able to set a new code. Which means that once you've entered the correct password, you have a certain time period to enter another code, I would probably make it 3 stars. If that code is entered in time, it branches to another routine that allows you to enter the New Code. HOW? IF Keypress = "***" THEN . . . will not compile.
This is what I want to do. One of my bashful friends wants a gate controller for his business, and wants to change the combo when an employee leaves his service. I was thinking it would be useful to have several passwords and log the data as to who went through, probably a project beyond the scope of this PIC control, but maybe not if interfaced to a P/C. Old P/Cs are landfill fodder.


Obviously, if you forget the code, the only way to reset it is to reprogram the chip. For security, That's a good thing.

Don't try to add more pasta by stitching things in with the existing keypad routine. Create a separate routine that handles entering the new code, and branch to it at the appropriate time. There's only so much marinara sauce in the world. And I want some of it for my dinner.
Switching to rice noodles and seaweed - the Japanese stuff always works! :)

;----

Back to the EEPROM.

Location 0 is where the length of the Code is stored. The actual Code is stored from location 1 on.


Start at location 1, and store each keypress in successive locations. After they've finished entering the code (with a # sign), store the number of digits they entered in location 0.
<br>


Data @0, 5, "78A5D" ; Length of, and The Combination

change using:
WRITE 1, 12345
or
WRITE 1, ByteA ?
how do I get byteA to have the value of new combo?
@ READKEYPAD _ByteA
. . . Right?
Short of plugging PIC into the programmer how do I communicate with it?
JS

Darrel Taylor
- 15th February 2007, 23:11
HOW? IF Keypress = "***" THEN . . . will not compile.

In the original program, was there anything that looked like IF Keypress = "78A5D" THEN ?


@ READKEYPAD _ByteA
. . . Right?

Right. You can only Write (or read) 1 byte at a time to EEPROM.

I'm just sitting here waiting for you to come up some more ideas.

I could just write it for you ... but I won't.

I'll be over playing Trains with Malcolm. :)
<br>

Archangel
- 15th February 2007, 23:49
In the original program, was there anything that looked like IF Keypress = "78A5D" THEN ?

<br>


No there was not. I'm on standby for now as it is cold and dry in my shop and I think I ESD zapped my 2 877As, I reordered some today. I will port over some of the code to a smaller cheaper PIC while trying to develope this, I appreciate your patience Darrel, and your help., The wait will give me time to machine the keypad out of Aluminium fo outdoor use, the commercial key unit will donate its letter/numbered pad to this project, and real switches will be used. Funny the 877As I have, program and verify but do not work with this or other code, that's why I think ESD got to them.

EDIT: DOUGH! You mean like this?


if ComboPtr <= ComboLength then
Read ComboPtr, ByteA ; Get the digit from EEPROM
if Key = ByteA then ; is it the same ?
WRITE 1, ByteA

Darrel Taylor
- 16th February 2007, 07:09
Keep Thinking. :)

lloyd778
- 21st February 2007, 01:01
Thank you Darrel, mister_e and Joe S. for so much help on this project. I have a working gate operator now as seen at http://boogerdigger.com/gate1.htm using this code (attached zip file). I hope putting up a link is not against the rules. If so, let me know and I won't do it again.
There are 2 things that I want to add to my driveway gate:
1) a way to add and delete a user code with the keypad instead of reprogramming the PIC. I have failed at this countless times now. Please give me some direction if you can.
2) add two cameras to take a picture of the view from the keypad area (to capture the face of a possible intruder) and one to capture the license plate of the vehicle (a possible help for the less-than-zealous local police department). As the front gate is a long way from my building - about 200 feet or so, I'll need to store the pictures on some form of removable media although I haven't excluded wireless.

I think I'll work on #2 now as my brain is hurting from #1.

If anyone has any suggestions on either the change code or the camera please let me know.

Lloyd Edwards
- 22nd February 2007, 00:04
In my previous post (above), I failed to add a few comments to the Gate1.zip file. You'll notice that it won't compile with keypad1.bas. Just remove the "1" and it should be fine. Shame on me for modifying the original file for a different app and then renaming yet another original with the "1". Confusion to the enemy or is it simply the confussion of my mind?
I do get a Warning[221] when I complie. ...gate1.asm143:Invalid message number (230). Dawged if I can figure this one out but the programs runs just fine.
Can't hardly wait to Eagle up a PCB for this project. Better wait a bit more as I just keep adding a bell here and a whistle there.
Someone say whistle? Hum, the bad guys enter the wrong code and a very loud siren blasts away. More humane than 6000 volts through keypad. Like that, a lot.

mister_e
- 22nd February 2007, 00:12
If i use the suggested PIC16F877A... it compile just fine.. no warning no nothing here.

Warning 230: __CONFIG has been deprecated for PIC18 devices. Use directive CONFIG.

so you're using a PIC18Xxxxx device. You have few choices
leave it like this... anyway it's a WARNING
you add @ ERRORLEVEL -230 at the top of your code
you use the new CONFIG syntax
you update your PBP version to 2.47... which take care of it.

Lloyd Edwards
- 22nd February 2007, 00:22
@ ERRORLEVEL -230 was at the top of the code. When I commented it out the warning went away and I got a clean compile. I love it all clean like that. Thanks mister_e!!

Lloyd Edwards
- 22nd February 2007, 01:05
Attached files are the cleaned up Gate1_1 code with no compile warnings and the origional KeyPad include reference restored. Also included is the KeyPad.bas file ready made. Just copy the unzipped KeyPad.bas file into your - I suppose - c:\program files\mecanique\mcs folder and you should be good to go. Play with it for a while and when you figure out how to change the user code with the keypad please share with the rest of us.

mister_e
- 22nd February 2007, 01:11
How about using the same method as home alarm already use?

You have 1 master code (service code), once you have enter it, you jump to a specific routine.

Lloyd Edwards
- 22nd February 2007, 01:20
Yes, mister_e, that is exactly the line that I must follow.