#rem
AlphaLEDClockDispChk.bas This is the clock with the green line of LEDs in a wood cabinet
It is used with a PC keyboard with PS/2 connector
John Saunders 10/17/2014 This ran from 10/17/2014 to 1/10/2015 OK. Needs only different month timer and sounds
1/10/2015 Moved power out code to transmit RF
2/42015 Added transmit each min date and time++
3/12/2015 Corrected TXDate_Time call error. 3/13/2017 Added Checksum to time message
10/8/2018 added padding to SEROUT
3/14/2020 increased transmit prepulse to 20 from 15 ms
3/25/2020 Send command twice
4/21/2022 Turn off time transmission in line 200 percharacter 20 in the variable message
DS1307 address map:
0-7 maintained by the clock - see DS-1307 data sheet
8 = Page to display (0-8), 9 = Blinking Character position (0-22), 10 = Timer index (0-5),11 = IR Command.
12 - 39 = 7 Daily timers each having 4 bytes in this order.:
Hour, Minute, Rate and its parameter in one byte & Type, also with a parameter in the last byte.
4 - 63 A variable message which may be re-written without reloading the Picaxe.
The 8 pages are selected by the ESC, F1-F9 buttons:
Page descriptions
0 Display Current time,day(string) month(string) date, temperature
1 Display fixed message 1
2 Display fixed message 2
3 Display fixed message 3
4 Display fixed message 4
5 Display variable message
6 Set hour minute day month date year
7 Display selected timer number, Set timer Hour Minute Rate Type
8 Edit variable message
Daily timer Rate codes:
Q = Every quarter hour. The parameter (1) may limit the active hours, or to daylight (2-15).
H = Every hour at the timer minute setting, paramerers as for Q.
D = Every day at the timer hour and minute settings. No parameter.
W = A specific day in the parameter (1=Sunday) at the timer hour and minute settings.
M = As for D but only for the date in the Yearly date setting.
The parameter selects either the A (A) or B (B) yearly timer.
y = As for M but also including the month in the Yearly month setting..
Daily timer Type codes:
P = Change page. 0-5 parameter.
S = Make a sound selected by the parameter (0-7).
Hex (2A - 7F) = Send an ASCII coded RF transmission..
#endrem
#picaxe 18M2
rem variables
rem general
symbol Iter = b2
symbol Mask = b3
symbol BitPos = b4
symbol Units = b5
symbol Tens = b12
symbol Scratch = b6
rem Specific content
symbol Request = Bit1 'The command processor asks for RTC access
symbol Phase = bit2 'Current value of the 1 Hz square wave
symbol OldPhase = bit3 'Previous value of the 1 Hz square wave
symbol PwrState = bit4 'The state of the PwrOut port
symbol NewInput = bit5
symbol TimeTxEn = bit6 '1 enables time and date transmissions every minute
symbol Page = b1 '0=normal,1=set Time&date,2=set timers,3=Set year,4-7=messages
symbol ADCData = w13 'Temperature
symbol Template = b7 'EEPROM entry defining a display code
symbol Command = b8 'Content of RTC Address $0B, IR code received
symbol Bright = b9 'Adjusted photocell reading
rem data
symbol CharData = b10 'A displayable value
symbol DECData = b11 'Binary value
symbol BCDData = b13 'Binary-coded decimal data
symbol Chcksum = b21
symbol ChckHex = b22
rem pointer
symbol Seconds = b14 'Selects the timer do check once a minute
symbol DispAddr = b15 'Position of the next character oon the display
symbol NvAddr = b16 'An address in the EEPROM
symbol RTCAddr = b17 'An address in the DS1307 real-time clock chip
symbol DispIndex = b18 'The position in the EEPROM of the next template code to be evaluated
symbol TimerIndex = b19 'The selected timer 0-5
symbol BlinkPos = b20 'The character position to blink during setup
rem outputs
symbol SRCLK = B.0 'Shift register clock conn pin 2
symbol DispWR = B.2 'Display write line - low active conn pin 6
symbol DispBL = B.3 'Display blanking PWM conn pin 4
symbol SRIN = B.5 'Shift register data in conn pin 9
symbol CLR = B.6 'Shift register & display clear - low active conn pins 3 & 8
symbol Grant = B.7 'Grants Control access to RTC
symbol Audio = C.3 'To RCa Jack on rear panel, AC only
symbol PwrOut = C.0 'Controlled line output on rear panel
symbol Tx_key = C.7 'Modulation for the transmitter
rem inputs
symbol PCIN = C.1 'Photocell analog input, conn pin 1
symbol TempIn = C.2 'Temperature sensor analog input, 10mv per deg F
symbol Rqst = pinC.5 'Request to Control processor to grant RTC access
symbol sqw = pinC.6 'RTC square-wave output, conn pin 11
rem rate codes:
symbol Dawn = $07
symbol Bedtime = $20
rem mask for shifting
DATA 0,(1,2,4,8,16,32,64) 'Mask of bits for DispChar
rem Day and month abbreviations
DATA 7,("SunMonTueWedThuFriSat")
DATA 28,("JanFebMarAprMayJunJulAugSepOctNovDec")
#rem
page templates. 0=tenplate terminator; 3 = day code, 4=temperature, 5 = month code,6 = TimerIndex in ASCII
28 to 127 ASCII literals;
!28 - 150 NvAddresses of fixed strings
228 - 243: Storage Addresses + 200
#endrem
DATA 69,(230,":",229,":",228," ",3," ",5," ",232," ",4,$1C,0) 'Page 0 (Clock) template, length 15
DATA 84,(128,230,":",229,":",228," ",231," ",233,"/",232,"/",234,0) 'Page 6 (Clock set) template length 15
DATA 99,(133,6," ",240,":",241," ",242," "," ",243,0) 'Page 7 (Timer set) template, length 15
rem variable length fixed strings
DATA 128,("Set:",0) 'length 5
DATA 133,("Timer#",0) 'length 7
DATA 141,("OFF",0) 'length 4
rem Fixed messases - each 25 length or less
DATA 155,("John Loves Elaine ")
DATA 180,("Message #2 ")
DATA 205,("Bingo ")
DATA 230,("Take out all the trash! ")
startup:
SETFREQ m16
HIGH CLR
LOW Tx_Key
HIGH SRCLK
HIGH DispWR
HIGH DispBL
LOW Audio
LOW PwrOut
LET Page = 0
ADCCONFIG %00000011
LOW Grant
main:
rem allow control processor access to the RTC when requested
LET Request = Rqst 'This is the handshake to permit the Control Processor to turn
IF Request = 1 THEN 'on the relay whih connects it to the RTC I2C lines at its request
HIGH Grant
DO
LET Request = Rqst
PAUSE 1
LOOP WHILE Request = 1
LOW Grant
PAUSE 5
LET NewInput = 1
ENDIF
rem Dim the display
FVRSETUP FVR4096 'To get temperature independent of supply voltage
ADCCONFIG %00000000
READADC PCIN,ADCData 'Dims the display according to ambient light
LET ADCData = 255 - ADCData
IF ADCData < 12 THEN
LET Bright = 35
ELSEIF ADCData > 43 THEN
LET Bright = 128
ELSE
LET Bright = 3 * ADCData
ENDIF
PWMOUT DispBL,65,Bright
LET Phase = sqw
rem Blink processing and timer evaluation on phase 0 - Time update occurs now
IF Phase = 0 AND OldPhase = 1 THEN
IF Page > 5 THEN 'Blinking is enabled
LET CharData = " "
LET DispAddr = BlinkPos & $1F
GOSUB DispChar
IF Page = 6 THEN
GOSUB DispChar
ENDIF
IF Page = 7 AND BlinkPos < 15 THEN 'The Timer hours and minute fields
GOSUB DispChar
ENDIF
ENDIF
PEEK 28,BCDData 'Current seconds
IF BCDData < 8 THEN
GOSUB TimeCheck 'Minute processing
ELSEIF BCDData = 8 AND TimeTxEn = 1 THEN
GOSUB TXDate_Time
ENDIF
ENDIF
rem Update display on phase 1
IF Phase = 1 AND OldPhase = 0 THEN 'Get all required DS1307 RTC contents
I2CSLAVE %11010000,i2cslow,i2cbyte
LET bptr = 28
READI2C 0,(@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptr,Page,BlinkPos,TimerIndex,Command)
WRITEI2C $0B,(0) 'Clear the command in the RTC
rem some checks
IF Page > 8 THEN
LET Page = 0
ENDIF
IF BlinkPos > 23 THEN
LET BlinkPos = 0
ENDIF
IF TimerIndex > 6 THEN
LET TimerIndex = 0
ENDIF
rem Is this a direct command?
IF Command > $2A THEN 'Transmit a RF command
GOSUB TransmitRF
ENDIF
LET Command = 0
rem Store data of the timer being edited if in page 7
IF Page = 7 THEN
LET RTCAddr = 4 * TimerIndex + 12
LET bptr = 40
READI2C RTCAddr,(@bptrinc,@bptrinc,@bptrinc,@bptr) 'Hour,minute,rate,type
ENDIF
rem Store the data of the timer selected by the first 7 seconds of the minute
PEEK 28,BCDData 'Seconds
LET RTCAddr = 0
LOOKUP BCDData,(12,16,20,24,28,32,36),RTCAddr
LET bptr = 44
IF RTCAddr <> 0 THEN 'Spread out the timers checks over the first 6 seconds of each minute
READI2C RTCAddr,(@bptrinc,@bptrinc,@bptrinc,@bptr) 'Hour,minute,rate,type
ENDIF
rem Store the variable message if in pages 5 or 8
IF Page = 5 or Page = 8 THEN
LET bptr = 48
READI2C $28,(@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptr)
ENDIF
rem Check fot time and date transmission update status
READI2C 60,(Chardata) 'Position 20 of the variable message, should be N or F
IF Chardata = "F" THEN
timeTxEn = 0
ELSE
timeTxEn = 1
ENDIF
GOSUB Update
ENDIF
LET OldPhase = Phase
goto main
END
TransmitRF:
IF Command = "+" THEN 'Q sends =/+
HIGH PwrOut
ENDIF
IF Command = "-" THEN
LOW PwrOut
ENDIF
SETFREQ m8
HIGH Tx_Key 'This pulse unlocks the receiver
PAUSE 40
LOW Tx_Key
PAUSE 20
SEROUT TX_Key,N2400_8,("14L1776",Command,13,10) 'The CR,LF is for debugging
PAUSE 200
HIGH Tx_Key 'This pulse unlocks the receiver
PAUSE 40
LOW Tx_Key
PAUSE 20
SEROUT TX_Key,N2400_8,("14L1776",Command,13,10)
SETFREQ m16
RETURN
DispChar: 'shifts 8 bits address then 8 bits character LSB first, then load display
'Input is Chardata and DispAddr
'At 8MHz with no rewrite, time is 3.2 ms, with rewrite 33.4 ms, total 206 ms, 1 rewrite
'At 32MHz with no rewrite, time is 2.3 ms, with rewrite 10 ms, total 209 ms, 1 rewrite
'Gap between characters = 5.8 ms
LET BitPos = $50 + DispAddr
PEEK BitPos,Mask
IF Mask = CharData OR DispAddr > 23 OR CharData < $1B THEN
GOTO ItsSame
ELSE
POKE BitPos,CharData
ENDIF
FOR BitPos = 0 TO 4
READ BitPos,Mask
LET Mask = DispAddr & Mask
LOW SRIN
IF Mask = 0 then Addrbitislow
HIGH SRIN
Addrbitislow:
PULSOUT SRCLK,1
NEXT
LOW SRIN
PULSOUT SRCLK,1
HIGH SRIN 'CU is high
PULSOUT SRCLK,1
PULSOUT SRCLK,1
FOR BitPos = 0 TO 6
READ BitPos,Mask
LET Mask = CharData & Mask
LOW SRIN
IF Mask = 0 then Charbitislow
HIGH SRIN
Charbitislow:
PULSOUT SRCLK,1
NEXT
PULSOUT SRCLK,1
PULSOUT DispWR,1
ItsSame:
IF CharData <> 0 THEN
INC DispAddr
ENDIF
RETURN
DispDec: 'Displays DECData (byte) at current address position in Digital as 3 characters
LET Tens = DECData / 100
LET Units = DECData // 100
IF Tens = 0 THEN
LET CharData = " "
ELSE
LET CharData = Tens + "0"
ENDIF
GOSUB DispChar
LET CharData = Units / 10 + "0"
GOSUB DispChar
LET CharData = Units // 10 + "0"
GOSUB DispChar
RETURN
DispBCD:
BCDTOASCII BCDData,Tens,Units
IF Tens <> "0" OR Page <> 0 THEN 'Omit leading 0 only in page 0
LET CharData = Tens
GOSUB DispChar
ENDIF
LET CharData = Units
GOSUB DispChar
RETURN
DispHex: 'Input is in Units
IF Units < 10 THEN
LET Chardata = Units + "0"
ELSE
LET Chardata = Units + "7"
ENDIF
GOSUB DispChar
RETURN
DispString: 'Displays a null-terminated string at EEPROM address NVAddr at DispAddr
DO
READ NvAddr,CharData
INC NvAddr
GOSUB DispChar
LOOP WHILE CharData <> 0 AND DispAddr < 24
RETURN
DispFixed: 'Displays a 24 character string at EEPROM address NVAddr at beginning
DO
READ NvAddr,CharData
INC NvAddr
GOSUB DispChar
LOOP WHILE DispAddr < 24
RETURN
DispVariable:
LET DispAddr = 0
FOR Iter = 48 TO 71
PEEK Iter,Chardata
GOSUB DispChar
NEXT Iter
RETURN
BlankEOL:
DO WHILE DispAddr < 24
LET CharData = " "
GOSUB DispChar
LOOP
RETURN
DispDOW: 'Day of week as a string
PEEK 31, BCDData 'Bits 0-2 are day of week
LET NVAddr = 3 * BCDData + 4 'Day of week strings start at 7, Sunday is day 1
FOR Iter = 0 to 2
LET Scratch = NVAddr + Iter
READ Scratch,CharData
GOSUB DispChar
NEXT Iter
RETURN
DispMonth: 'Month as a string
PEEK 33,BCDData 'Bits 0-3 are month, 4 is tens of month
LET Units = BCDData & $0F
LET Tens = BCDData & $10
IF Tens = 0 THEN
LET NvAddr = 3* Units + 25 'Date strings start at 28, January is 1
ELSE
LET NvAddr = 3* Units + 55 'Oct-Dec strings start at 55, October is $10
ENDIF
FOR Iter = 0 to 2
LET Scratch = NVAddr + Iter
READ Scratch,CharData
GOSUB DispChar
NEXT Iter
RETURN
DispTemperature: 'Right-justified at position 20, pos 23 is for deg F character ($1C)
rem first write spaces to position 20
DO WHILE DispAddr < 20
LET CharData = " "
GOSUB DispChar
LOOP
FVRSETUP FVR4096 'To get temperature independent of supply voltage
READADC10 TempIn,ADCData
LET DecData = ADCData / 4
GOSUB DispDec
RETURN
Update:
IF NewInput=1 THEN
SERTXD ("Page=",#Page,",BlinkPos=",#BlinkPos,",TimerIndex=",#TimerIndex,",Command=",#Command,13,10)
LET NewInput = 0
ENDIF
LET DispAddr = 0
LET DispIndex = 0
LOOKUP Page,(69,155,180,205,230,5,84,99,8),DispIndex
IF DispIndex = 0 THEN
RETURN
ENDIF
IF DispIndex = 5 OR DispIndex = 8 THEN 'variable message
GOSUB DispVariable
RETURN
ENDIF
IF DispIndex > 150 AND DispIndex < 250 THEN
LET NvAddr = DispIndex
GOSUB DispFixed
RETURN
ENDIF
DO
READ DispIndex,Template
SELECT Template
CASE 0
GOSUB BlankEOL
CASE 4
GOSUB DispTemperature
CASE 3
GOSUB DispDOW 'as a 3-character string
CASE 5
GOSUB DispMonth 'as a 3-character string
CASE 6 'The current timer
LET CharData = TimerIndex + $31
GOSUB DispChar
CASE 28 TO 127 'An ASCII displayable character
LET CharData = Template
GOSUB DispChar
CASE 128 TO 141
LET NvAddr = Template
GOSUB DispString
CASE 228 TO 243
LET Scratch = Template - 200 'Address in storage
PEEK Scratch,BCDData 'The value
rem Specials
IF Scratch = 42 OR Scratch = 43 THEN 'Timer rate and type
LET Tens = BCDData / 16
LET Units = BCDData & $0F
IF Scratch = 42 THEN 'The Rate setting
IF Tens = 0 THEN 'OFF
LET NvAddr = 141
GOSUB DispString
GOSUB BlankEOL
ELSE
LET CharData = " "
LOOKUP Tens,("X","T","H","D","W","M","N","Y"),Chardata
IF CharData <> " " THEN
GOSUB DispChar
ENDIF
LET Chardata = Units
GOSUB DispHex
ENDIF
ENDIF
IF Scratch = 43 AND DispAddr < 22 THEN 'The Type setting, if not OFF
LET CharData = " "
LOOKUP Tens,("P","S","2","3","4","5","6","7"),Chardata
IF Chardata <> " " THEN
GOSUB DispChar
ENDIF
LET Chardata = Units
GOSUB DispHex
ENDIF
ELSE
GOSUB DispBCD
ENDIF
ELSE
LET CharData = " "
GOSUB DispChar
ENDSELECT
INC DispIndex
LOOP WHILE DispAddr < 24 AND Template <> 0
RETURN
TimeCheck:
#rem
The second of detection and immediate action is when this subroutine is called
Each of the 6 timers (0-6) has a base RTC address of 12,16.20,24, 28 and 32. These contain BCD numbers
Each Timer has 4 bytes at at these 4 base addresses.
Some timers use the Month in 12 or 14 and the date in 13 or 15, as "A' (12,13) or "B" (14,15)
The 4 bytes are Hour, Minute, Rate and Type. They are in locations 28 - 31
Rate. Its upper 4 bits (MSN) is the rate interval as follows (using the displayed value)
The least significant is a parameter.
Disabled (0="X")
Ten Minutes (1="T") every ten minutes at the given minute. Parameter may limit hours
Hourly (2="H") every hour at the minute setting Parameter may limit hours
Daily (3="D") every day at the hour and the minute, Parameter not used
Weekly (4="W") every week at the hour and the minute and the day in the Parameter (1-7), displayed as the ASCII number
Monthly1 (5="M") every month at the hour and the minute and the date 1 - 15 in the parameter as 1 - 15
Monthly2 (6="N") every month at the hour and the minute and the date 16 - 31 in the parameter as 0-15
Yearly (7="Y") every year at the month in the parameter, the date in the hours field and the hour in the minutes field
#endrem
rem Split up the rate byte of the indicated timer
PEEK 46,BCDData 'Seconds Timer Rate byte
LET Tens = BCDData / 16
IF BCDData =0 THEN NoMatch 'This Timer is OFF
LET Units = BCDData & $0F 'Parameter of rate
rem First test those modes which check minutes
IF Tens < 7 THEN 'T,H,D,W,N,M
PEEK 29,BCDData 'Current Minutes
IF Tens = 1 THEN 'Special for T
LET BCDData = BCDData & $0F '0-9
ENDIF
PEEK 45,Chardata 'Timer minutes
IF BCDData <> CharData THEN NoMatch
ENDIF
rem T and H have restrictions
IF Tens = 1 OR Tens = 2 THEN
IF Units = 0 THEN Pass
PEEK 30,CharData 'Hours
IF Units = 1 AND CharData > Dawn AND CharData < Bedtime THEN Pass
LET Scratch = 6 * Units + 35 'Range of bright is 16 to 120
IF Units > 1 AND Bright > Scratch THEN Pass
GOTO NoMatch
ENDIF
rem Finished with T and H
IF Tens > 2 AND Tens < 7 THEN 'D,W,M & N - Check hour match next
PEEK 30,BCDData 'Current Hours
PEEK 44,CharData 'Timer hours
IF BCDData <> CharData THEN NoMatch
ENDIF
IF Tens = 3 THEN Pass 'Finished with Daily
IF Tens = 4 THEN 'W only Check the day of week
PEEK 31,BCDData 'Current Day of week
IF BCDData = Units THEN Pass
GOTO NoMatch
ENDIF
rem Finished with weekly
IF Tens = 5 OR Tens = 6 THEN 'M or N - Check the date
PEEK 32,BCDData 'Current Date
IF Tens = 6 THEN
LET Chardata = Units + 16
ENDIF
IF BCDData = CharData THEN Pass
ENDIF
rem Finished with monthly
rem Yearly, 7
rem Check Month
PEEK 33, BCDData 'Current Month
IF BCDData <> Units THEN NoMatch
rem Check Date
PEEK 32, BCDData 'Current date
PEEK 44, CharData 'Timer Hours field contains the date
IF BCDData <> Chardata THEN NoMatch
rem Check Hour
PEEK 31, BCDData 'Current hour
PEEK 45, CharData 'Timer minutes field contains the hour
IF BCDData <> Chardata THEN NoMatch
rem We only want one, at minute 0
PEEK 29,BCDData 'Current Minutes
IF BCDData <> 0 THEN NoMatch
Pass:
GOSUB TakeAction
NoMatch:
RETURN
TakeAction:
#rem
The action to be taken on a timer (per seconds) detection is determined by the byte in 19 (Type), which also has a MSN and a LSN
The choices at the MSN are displayed as::
0=Change page if not in a setting and not to a setting
1=Audio (1="A") Plays a sound as specified in the LSN (0 - 5) to the rear RCA speaker jack, displayed as the ASCII number
2 to 7 Transmit Sends a command using the ASCII code given by the action as hex
#endrem
rem Split up the type byte of the indicated timer
PEEK 47,BCDDAta 'The seconds timer Type byte
LET Tens = BCDData / 16
LET Units = BCDData // 16 'The parameter
IF Tens = 0 AND Units < 6 THEN 'Change page if not in a setting
LET Page = Units
WRITEI2C $08,(Page)
ENDIF
IF Tens = 1 THEN 'Audio
LET Scratch = 4 * Units
SOUND Audio,(56,Scratch)
ENDIF
IF Tens > 1 AND Tens < 8 THEN 'RF Transmission
LET Command = BCDData
GOSUB TransmitRF
LET Command = 0
ENDIF
RETURN
TXDate_Time:
LET Chcksum = 132 '3 commas
SETFREQ m8
HIGH Tx_Key 'This pulse unlocks the receiver
PAUSE 40
LOW Tx_Key
PAUSE 20
SEROUT TX_Key,N2400_8,("14L1776t,G,") 'G is code for 11 characters
FOR Scratch = 33 TO 29 STEP -1
IF Scratch <> 31 THEN 'Day of week not needed
PEEK Scratch, BCDData
LET Tens = BCDData / 16 + 48 'BCD data
LET Units = BCDData & $0F + 48 'Parameter of rate
SEROUT TX_Key,N2400_8,(Tens,Units,",")
LET Chcksum = Chcksum + Tens + Units
ENDIF
NEXT
LET ChckHex = ChckSum / 16
IF ChckHex < 10 THEN
LET Tens = ChckHex + "0"
ELSE
LET Tens = ChckHex + "7"
ENDIF
LET ChckHex = ChckSum & $F
IF ChckHex < 10 THEN
LET Units = ChckHex + "0"
ELSE
LET Units = ChckHex + "7"
ENDIF
'SEROUT TX_Key,N2400_8,(Tens,Units,13,10) 'The CR,LF is for debugging
SEROUT TX_Key,N2400_8,(Tens,Units,13,10,4,4,4,4,4,4,4,4,4,4) 'PADDING ADDED 10/8/2018
RETURN