Yup, there's Tons of different ways.
But first, why doesn't Joe's program work...
So here's one of those other ways. It has 2 security levels, timeouts, and an easy to set Code in EEPROM.
- 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.
Code:@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



on interrupt goto KeypadInt ; ON INTERRUPT ????


Bookmarks