Last edited by Archangel; - 10th February 2007 at 22:39.
If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
.
Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
.
There simply is no "Happy Spam" If you do it you will disappear from this forum.
This code doesn't work!.
Last edited by Leonardo; - 11th February 2007 at 02:17.
If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
.
Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
.
There simply is no "Happy Spam" If you do it you will disappear from this forum.
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...
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 => 7Code:' ' 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
and this...
could be replace by the single line bellow.Code: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"
Or store the table in the EEPROM, then read from it..Code:LOOKUP ByteA,[0,1,2,3,"A",4,5,6,"B",7,8,9,"C","*",0,"#","D"],ByteA
Code:DATA @1,1,2,3,"A",4,5,6,"B",7,8,9,"C","*",0,"#","D" ' ' ' ' ' Read ByteA, ByteA
Last edited by mister_e; - 11th February 2007 at 11:46.
Steve
It's not a bug, it's a random feature.
There's no problem, only learning opportunities.
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
DT
Nice one Darrel!
on interrupt goto KeypadInt ; ON INTERRUPT ????
![]()
Steve
It's not a bug, it's a random feature.
There's no problem, only learning opportunities.
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...
Code:' ' 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
Last edited by Leonardo; - 12th February 2007 at 03:25.
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
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.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 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
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!
Last edited by Archangel; - 12th February 2007 at 10:05.
If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
.
Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
.
There simply is no "Happy Spam" If you do it you will disappear from this forum.
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.Darrel, you said my code never went to gosub, . . . the if bytea != 0 then gosub combo, will not do 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.It recognizes the first digit of the combination, and sets combocount to 1Code:if ((ByteA = 7) and (combocount = 0)) then combocount = %00000001 pause 1000 else combocount = 0 endif
Then it continues on to the next IF statement...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.Code:if ((ByteA = 8) and (combocount = %00000001)) then combocount = %00000011 pause 1000 else combocount = 0 endif
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>
DT
Bookmarks