' ========================================================================= ' ' File....... Digi-Lock.BS2 ' Purpose.... Digital combination lock ' Author..... Jon Williams -- Parallax, Inc. ' E-mail..... jwilliams@parallax.com ' Started.... ' Updated.... 15 SEP 2005 ' ' {$STAMP BS2} ' {$PBASIC 2.5} ' ' ========================================================================= ' -----[ Program Description ]--------------------------------------------- ' ' Digital lock using an encoder and the Rentron SLED4C display ' -- See www.rentron.com/Products/SLED4C.htm ' -----[ Revision History ]------------------------------------------------ ' -----[ I/O Definitions ]------------------------------------------------- Encoder VAR INA ' encoder bits (0 & 1) NumSelect PIN 2 ' button input Solenoid PIN 3 ' latch control Enable PIN 4 ' SLED4C.5 / MC14489.10 Clock PIN 5 ' SLED4C.4 / MC14489.11 DataIO PIN 6 ' SLED4C.3 / MC14489.12 ' -----[ Constants ]------------------------------------------------------- Pressed CON 0 ' for active-low button NotPressed CON 1 IsOn CON 1 ' display control IsOff CON 0 Locked CON 0 ' lock states Has1 CON 1 Has2 CON 2 Open CON 3 ' MC14489 characters ' decode mode Ltr_A CON $0A ' Hex Ltr_b CON $0B ' Hex Ltr_C CON $0C ' Hex Ltr_c2 CON $01 ' Special Ltr_d CON $0D ' Hex Ltr_E CON $0E ' Hex Ltr_F CON $0F ' Hex Ltr_H CON $02 ' Special Ltr_h2 CON $03 ' Special Ltr_J CON $04 ' Special Ltr_L CON $05 ' Special Ltr_n CON $06 ' Special Ltr_O CON $00 ' Hex Ltr_o2 CON $07 ' Special Ltr_P CON $08 ' Special Ltr_r CON $09 ' Special Ltr_U CON $0A ' Special Ltr_u2 CON $0B ' Special Ltr_Y CON $0C ' Special Blank CON $00 ' Special or No ULine CON $08 ' No Dash CON $0D ' special Equal CON $0E ' Special DegSym CON $0F ' Special Colon CON %011 ' No (SLED4C) DegSym2 CON %100 ' No (SLED4C) #DEFINE ShowState = 1 ' 1 = show lock state ' -----[ Variables ]------------------------------------------------------- state VAR Nib ' lock state config VAR Byte ' configuration register dpCtrl VAR Nib ' decimal point control bank5 VAR Nib bank4 VAR Nib bank3 VAR Nib bank2 VAR Nib bank1 VAR Nib ' used for colon/deg pnt display VAR config.BIT0 ' 0 = off, 1 = on brightness VAR dpCtrl.BIT3 ' 1 = bright, 0 = dim encOld VAR Nib ' encoder readings encNew VAR Nib encA VAR encOld.BIT0 encB VAR encNew.BIT1 testVal VAR Byte ' for combination test dial VAR Byte ' -----[ EEPROM Data ]----------------------------------------------------- Combo DATA 07, 25, 62 ' -----[ Initialization ]-------------------------------------------------- Reset: LOW Solenoid ' lock it up HIGH Enable ' deselect SLED4C encOld = Encoder & %0011 state = Locked dpCtrl = %1000 ' on bright, no DPs GOSUB Update_Display ' -----[ Program Code ]---------------------------------------------------- Main: DO WHILE (NumSelect = NotPressed) encNew = Encoder & %0011 ' read encoder inputs IF (encNew <> encOld) THEN ' changed? dial = dial + 1 + (98 * (encA ^ encB)) // 100 encOld = encNew ' save current scan GOSUB Update_Display ' display new spnner value ENDIF LOOP DO : LOOP WHILE (NumSelect = Pressed) ' force release Check_Digit: READ (Combo + state), testVal ' get current combo num IF (dial = testVal) THEN ' test against spinner state = state + 1 // 4 ' update state if match ELSE state = Locked ' otherwise reset ENDIF GOSUB Update_Display Check_Activation: IF (state = Open) THEN Solenoid = IsOn ' activate solenoid DO PAUSE 100 ' flash timing display = display ^ 1 ' toggle display bit GOSUB Set_Cfg encNew = Encoder & %0011 ' scan encoder LOOP UNTIL (encNew <> encOld) ' wait until it moves GOTO Reset ' lock it up ENDIF GOTO Main ' -----[ Subroutines ]----------------------------------------------------- ' Update MC14489/SLED4C configuration register Set_Cfg: Enable = 0 ' enable SLED4C SHIFTOUT DataIO, Clock, MSBFIRST, [config] ' send config register Enable = 1 ' disable SLED4C RETURN ' Update MC14489/SLED4C bank values Set_Banks: Enable = 0 ' enable SLED4C SHIFTOUT DataIO, Clock, MSBFIRST, ' send control nibbles [dpCtrl\4, bank5\4, bank4\4, bank3\4, bank2\4, bank1\4] Enable = 1 ' disable SLED4C RETURN ' Shows current spinner value or "OPEn" Update_Display: IF (state < Open) THEN GOTO Show_Dial ELSE GOTO Show_Open ENDIF ' Show current dial value "_XX_" Show_Dial: dpCtrl = %1000 ' bright, no DPs bank5 = ULine bank4 = dial DIG 1 ' tens bank3 = dial DIG 0 ' ones bank2 = ULine #IF (ShowState = 1) #THEN ' update state LEDs (colon dots) LOOKUP state, [%0000, %0001, %0011], bank1 #ELSE bank1 = %0000 #ENDIF display = IsOff ' turn off display GOSUB Set_Cfg GOSUB Set_Banks config = %00100111 ' show "_XX_" GOSUB Set_Cfg RETURN ' Show "OPEn" Show_Open: dpCtrl = %1000 ' bright, no DPs bank5 = Ltr_O bank4 = Ltr_P bank3 = Ltr_E bank2 = Ltr_n bank1 = $0000 ' clear extra LEDs display = IsOff ' turn off display GOSUB Set_Cfg GOSUB Set_Banks config = %11010111 ' show "OPEn" GOSUB Set_Cfg RETURN