I saved the program as a text file.. I did not see how to upload it as an attachment so I pasted it below.
You are right that LPT ports are going away, and I also found my original program worked fine on some 98 computers but didn't on others so I went the Basic Stamp route as shown below... I'm pretty sure this is the latest verstion. I drive the speaker the same as I do the latch, through an opto. The additional hardware has the stamp, an onboard clock and a data-logger that I plug a thumb drive into. Anything I need to update other than the clock which I do from the keypad. The log file is kept on the thumb drive as well as the password files.
Code: Select all
' {$STAMP BS2pe}
' {$PBASIC 2.5}
' =========================================================================
'
' File...... Door1.BS2pe
' Purpose... Electronic door latch controller
' Author.... Daniel Fuller
' E-mail.... qxotic@hotmail.com
' Started... 11 August 2009
' Updated... 21 September 2009
' -----[ Program Description ]---------------------------------------------
'
' Provides entry control for a door.
'
' The (Grayhill series 88) keypad used for this program is layed out like this:
'
' --- --- ---
' | 1 | 2 | 3 | R1
' --- --- ---
' | 4 | 5 | 6 | R2
' --- --- ---
' | 7 | 8 | 9 | R3
' --- --- ---
' | * | 0 | # | R4
' --- --- ---
'
' C C C
' 1 2 3
' -----[ I/O Definitions ]-------------------------------------------------
TX PIN 0 ' Transmit Data to Logger --> 27937.4 (RXD)
RX PIN 1 ' Receive Data from Logger <-- 27937.5 (TXD)
SDA PIN 8 ' clock - used Sparkfun RTC BOB-00099
SCL PIN 9 ' clock
' -----[ Constants ]-------------------------------------------------------
Baud CON 188 'A baud rate of 4800
DS1307 CON %1101 <<4> 510)THEN start = 0
LOOP UNTIL (IN3 = 0) ' wait for key
key = ~KeyPad ' get inverted state of bits
IF (start <510>26 THEN
GOSUB ValidCode
ELSEIF clock(2)>6 AND clock(2)<22 THEN
GOSUB ValidCode
ELSE
Note = "Z":GOSUB InvalidCode ' set note for timezone denial
ENDIF
RETURN
' -----[ InvalidCode ]----------------------------------------------------
InvalidCode:
GOSUB Beep2
GOSUB Beep2
GOSUB Beep2
GOSUB History
GOSUB Main
' -----[ ValidCode ]----------------------------------------------------
ValidCode:
Note = "G" 'set note to 1 for access granted
HIGH 12 'send signal to open latch
GOSUB Beep2
GOSUB Beep
PAUSE 2500 'delay to keep latch open
LOW 12 'send signal to close latch
GOSUB Beep2
GOSUB History
GOSUB Main
' -----[ History ]----------------------------------------------------
History: 'this info goes into a history log on logger
GOSUB Check_Logger
SEROUT TX, Baud, [$01, $20, "Log.txt", $0D] ' DIR
SERIN RX, Baud, 500, No_Log,[WAIT($20)] ' Wait for $20 or time out if no response
SEROUT TX,Baud,[$9,$20,"Log.txt", CR]
SERIN RX,Baud,500, LogErr2,[WAIT(">")]
SEROUT TX,Baud,[$8,$20,$0,$0,$0,DEC 24,CR,DEC2 Apt," ",DEC4 keycode,
" ", Note," ",
HEX2 clock(2),":",HEX2 clock(1)," ",
HEX2 clock(6),HEX2 clock(5),HEX2 clock(4),CR,$0A,CR]
SERIN RX,Baud,500, LogErr3,[WAIT(">")]
SEROUT TX,Baud,[$0A,$20,"Log.txt", CR]
SERIN RX,Baud,500, LogCloseErr,[WAIT(">")]
DEBUG CR,? Apt, ? keycode, ASC ? Note 'this data went to History Log
DEBUG HEX2 clock(2), ":", HEX2 clock(1), ":", HEX2 clock(0), CR
DEBUG "20", HEX2 clock(6), "-", HEX2 clock(5), "-", HEX2 clock(4), CR
RETURN
'-----[ Logger Error checks for Log file]-----------------------------------------------
LogErr2:
Note = "M"
GOSUB InvalidCode
LogErr3:
Note = "N"
GOSUB InvalidCode
LogCloseErr:
Note = "P"
SEROUT TX,Baud,[$0A,$20,"Log.txt", CR]
GOSUB InvalidCode
No_Log:
SEROUT TX,Baud,[$9,$20,"Log2.txt", CR] ' create second log file if log is corrupted
SERIN RX,Baud,500, LogErr2,[WAIT(">")]
SEROUT TX,Baud,[$8,$20,$0,$0,$0,DEC 24,CR,DEC2 Apt," ",DEC4 keycode,
" ", Note," ",
HEX2 clock(2),":",HEX2 clock(1)," ",
HEX2 clock(6),HEX2 clock(5),HEX2 clock(4),CR,$0A,CR]
SERIN RX,Baud,500, LogErr3,[WAIT(">")]
SEROUT TX,Baud,[$0A,$20,"Log2.txt", CR]
SERIN RX,Baud,500, LogCloseErr,[WAIT(">")]
GOSUB Main
' -----[ Use Keypad to Update Clock ]----------------------------------------------------
KP_Clock_Update:
GOSUB Beep ' 4 beeps for ready for time and date entry
GOSUB Beep
GOSUB Beep
GOSUB Beep
GOSUB GetKeyPad
IF keyIn <>4 THEN GOSUB InvalidCode 'sub password
GOSUB Beep
GOSUB Beep2
counter = 12
DO
GOSUB GetKeyPad
counter = counter - 1
kpEntry(counter) = keyIn
LOOP UNTIL counter = 1
clock(1) = kpEntry(2) * 10 + kpEntry(1)
clock(1) = clock(1) // 60 'update mins
clock(1) = (clock(1) / 10 << 4) + (clock(1) // 10)'decimal to BCD
clock(2) = kpEntry(4) * 10 + kpEntry(3)
clock(2) = clock(2) // 24 'update hours
clock(2) = (clock(2) / 10 << 4) + (clock(2) // 10)'decimal to BCD
clock(3) = kpEntry(5)
clock(3) = clock(3) // 7 'update day of week
clock(3) = (clock(3) / 10 << 4) + (clock(3) // 10)'decimal to BCD
clock(4) = kpEntry(7) * 10 + kpEntry(6)
clock(4) = clock(4) // 31 'update day of month
clock(4) = (clock(4) / 10 << 4) + (clock(4) // 10)'decimal to BCD
clock(5) = kpEntry(9) * 10 + kpEntry(8)
clock(5) = clock(5) // 12 'update month
clock(5) = (clock(5) / 10 << 4) + (clock(5) // 10)'decimal to BCD
clock(6) = kpEntry(11) * 10 + kpEntry(10)
clock(6) = (clock(6) / 10 << 4) + (clock(6) // 10)'decimal to BCD
clock(0) = $00
clock(7) = 0
GOSUB Set_Clock
GOSUB Get_Clock
DEBUG CR, HEX2 clock(2), ":", HEX2 clock(1), ":", HEX2 clock(0), CR
DEBUG ? clock(3), CR
DEBUG "20", HEX2 clock(6), "-", HEX2 clock(5), "-", HEX2 clock(4), CR
RETURN
' --------[ I2C Clock Subroutines ] ----------------
Set_Clock:
PAUSE 100
I2COUT SDA, DS1307, 0, [STR clock\8] ' update clock registers
RETURN
Get_Clock:
PAUSE 100 ' wait 100 ms CHANGE IF MORE CODE IS ADDED !!!
I2CIN SDA, DS1307, 0, [STR clock\8] ' retrieve clock registers
RETURN
' --------[ Beeps ] ----------------
Beep:
HIGH 14 'beep for ready
PAUSE 200
LOW 14
PAUSE 100
RETURN
Beep2:
HIGH 14 'beep for ready
PAUSE 200
LOW 14
PAUSE 200
RETURN
'------------( Code Update )----------------------------------
Code_Update:
GOSUB Beep ' 2 beeps for ready for Code update
GOSUB Beep
GOSUB GetKeyPad
IF keyIn =2 THEN GOSUB Add_Code ELSEIF keyIn = 3 THEN GOSUB Delete_Code ELSE GOSUB InvalidCode
RETURN
' --------[ Add PassCode ] ----------------
Add_Code:
GOSUB Code_Loop
GOSUB Check_Logger
SEROUT TX,Baud,[$9,$20, DEC4 keycode, CR] ' creates file
SERIN RX,Baud,500, LogErr2,[WAIT(">")]
SEROUT TX,Baud,[$8,$20,$0,$0,$0,DEC 2,CR,DEC2 Apt,CR] 'writes Apt no to file
SERIN RX,Baud,500, LogErr3,[WAIT(">")]
GOSUB Close_Logger
GOSUB Beep
GOSUB Beep
DEBUG CR,? Apt, ? keycode
RETURN
' --------[ Delete PassCode ] ----------------
Delete_Code:
GOSUB Code_Loop
GOSUB Check_Logger
SEROUT TX,Baud,[$07,$20,DEC4 keycode,CR] 'deletes file
SERIN RX,Baud,500,DeleteErr,[WAIT(">")]
GOSUB Beep
GOSUB Beep
DEBUG ? keycode, CR
RETURN
DeleteErr:
DEBUG "file delete error", CR
GOSUB InvalidCode
' --------[ Loop for Code Input ] ----------------
Code_Loop:
GOSUB Beep
counter = 0
keycode = 0
DO
GOSUB GetKeyPad
counter = counter + 1
kpEntry(counter) = keyIn
LOOP UNTIL counter = 6
keycode = kpEntry(1) * 10
keycode = keycode + kpEntry(2)
keycode = keycode * 10
keycode = keycode + kpEntry(3)
keycode = keycode * 10
keycode = keycode + kpEntry(4)
Apt = kpEntry(5) * 10
Apt = Apt + kpEntry(6)
RETURN
' --------[ Check Logger ] ----------------
Check_Logger:
PAUSE 100 ' Allow Time To Settle
SEROUT TX, Baud, [CR]
SERIN RX,Baud,500,Not_Found2,[WAIT(">")]
RETURN
Not_Found2:
Note = 2
GOSUB InvalidCode
' --------[ Clear Variables ] ----------------
Clear_Variables:
counter = 0
key = 0
keyIn = 0
Apt = 0
Note = 0
start(1) = 0
keycode = 0
HIGH 2 ' shut logger power off
RETURN