'PICAXE-20X2
'NEO-6M GPS Module TX Data connected to hserin
'should work with any GPS sending NMEA messages
#picaxe 20x2
#Terminal 38400
'US DST starts second Sunday in March and ends first Sunday in November at 2:00 a.m. local time.
'UTC is ahead of local, so start in UTC is 10:00 AM (no DST) and end is 9:00 AM (DST)
setfreq m32
Symbol LED = C.5
Symbol ptro = B22 'used for scratchpad pointer
Symbol ptrn = B23 'used for scratchpad pointer
Symbol ptrp = B24 'used for scratchpad pointer
Symbol spd = B25 'var for data from scratchpad
Symbol spd2 = B29 'var for data from scratchpad
Symbol hhu = B26 'hour
Symbol mm = B27 'minute
Symbol ss = B28 'second
Symbol ddu = B30 'day
Symbol mou = B31 'month
Symbol yyu = B32 'year
Symbol tz = B33 'time zone offset
Symbol tadj = B34 'tz offset with or without DST
Symbol hhl = B35 'Local Hour
Symbol ddl = B36 'Local Day
Symbol mol = B37
Symbol yyl = B38 'Local Year
Symbol dstd = B39 'DST Start Day in March
Symbol dstdn = B40 'DST End Day in November
Symbol pme = B41 'prior month end date
Symbol D1 = B42 'code for display digit 1 (leftmost)
Symbol D2 = B43 'code for display digit 2
Symbol D3 = B44 'code for display digit 3
Symbol D4 = B45 'code for display digit 4
Symbol DX = B46 'used in number to code convert
Symbol mdh = W26 'DST Start Day/Hour
Symbol lmdh = W27 'Local Day/Hour
Symbol ww1 = W25 'Temp word variable
Symbol ww2 = W24 'Temp word variable
'Time Zone and DST adjustments are designed for locations West of Greenwich (negative adjustment)
'Pacific Time Zone offset (will be subtracted from UTC)
tz = 8
'Table for number of days in months, starts with last day of December which is rollback date for January.
table 1,(31,31,28,31,30,31,30,31,31,30,31,30)
'Table of US DST start dates (March) from 2016 onwards
table 16, (13,12,11,10,8,14,13,12,10,9,8,14,12,11,9,10,14,13,12,11,10)
'Display setup
Hi2cSETUP i2cmaster,%11100000, i2cfast_32, i2cbyte
PAUSE 10 ; wait 1 ms for the display chip to initialise
Hi2cOUT ($21) ; start clock
Hi2cOUT ($E2) 'set bright
Hi2cOUT ($A0) ; set all rows on
Hi2cOUT ($80) ; turn off the display
'PAUSE
Hi2cOUT ($81) ; turn on the display
'address increments by 2 for each digit
Hi2cOUT (0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
gosub disptest
'US DST starts at 2AM second Sunday in March (so date will always be >7) and ends 2AM first Sunday in November
'November day is always (March day minus 7) so we only need to store March.
'2016 March 13 November 6
'2017 March 12 November 5
'2018 March 11 November 4
'2019 March 10 November 3
'2020 March 8 November 1
'2021 March 14 November 7
'2022 March 13 November 6
'2023 March 12 November 5
'2024 March 10 November 3
'2025 March 9 November 2
'2026 March 8 November 1
'2027 March 14 November 7
'2028 March 12 November 5
'2029 March 11 November 4
'2030 March 9 November 2
'2031 March 10 November 3
'2032 March 14 November 7
'2033 March 13 November 6
'2034 March 12 November 5
'2035 March 11 November 4
'2036 March 10 November 2
Top:
hsersetup b19200_32, %00 ' set the serial baud rate
Again:
ptr = 0
'wait for data $GPRMC message from gps and go to whoops if it doesn't arrive before timeout
hserin [10000,whoops],0,63,("R")
'check for "MC" (77 67) in scratchpad
get 0,spd
get 1,spd2
if spd <> 77 OR spd2 <> 67 then Again
Hi2cOUT (0x04,0x00)
'scan for delimiters and store positions in scratchpad starting @ 100
ptrn = 100
for ptr = 0 to 62
if @ptr = "," and ptrn < 127 then
put ptrn,ptr
ptrn = ptrn + 1
endif
next
'get the time/date from scratchpad
get 100,ptrp
gosub getdata
hhu = spd
gosub getdata
mm = spd
gosub getdata
ss = spd
get 108,ptrp
gosub getdata
ddu = spd
gosub getdata
mou = spd
gosub getdata
yyu = spd
goto dststuff
getdata:
'gets time/date data and converts ASCII to numeric
ptrp = ptrp + 1
ptrn = ptrp + 1
get ptrp, spd
get ptrn, spd2
spd = spd - 48
spd2 = spd2 - 48
spd = spd * 10 + spd2
ptrp = ptrp+1
return
dststuff:
spd = 0
spd2 = 0
if mou <= 2 OR mou > 11 then 'Dec - Feb always 100% no dst
tadj = tz
goto timefix
endif
if mou > 3 and mou < 11 then 'Apr to Oct always 100% dst
tadj = tz-1
goto timefix
endif
'get the dstdate
yyu=18
readtable yyu,dstd
'March
if mou = 3 and ddu < dstd then 'no dst
tadj = tz
goto timefix
endif
if mou = 3 and ddu > dstd then 'dst
tadj = tz-1
goto timefix
endif
if mou = 3 and ddu = dstd and hhu < 10 then 'no dst
tadj = tz
goto timefix
endif
if mou = 3 and ddu = dstd and hhu >= 10 then 'dst
tadj = tz-1
goto timefix
endif
'November
dstd = dstd - 7 'dst date in Nov
if mou = 11 and ddu < dstd then 'dst
tadj = tz-1
goto timefix
endif
if mou = 11 and ddu > dstd then 'no dst
tadj = tz
goto timefix
endif
if mou = 11 and ddu = dstd and hhu < 9 then 'dst
tadj = tz-1
goto timefix
endif
if mou = 11 and ddu = dstd and hhu >= 9 then 'no dst
tadj = tz
goto timefix
endif
timefix: 'adjusts UTC to local standard or daylight time
pause 2000
yyl = yyu 'may change later
mol = mou 'may change later
ddl = ddu 'may change later
'not first day of month
if ddu <> 1 then
'sertxd ("1 ")
if tadj <= hhu then 'simple case, zone adjustment can be deducted from hour.
'sertxd ("2 ")
hhl = hhu - tadj
else 'but if tadj is > hhu then the zone adjustment will roll back past midnight and we must change the date.
hhl = hhu - tadj + 24
ddl = ddu - 1
endif
endif
'first day of month
if ddu = 1 then
if tadj <= hhu then 'simple case, zone adjustment can be deducted from hour
hhl = hhu - tadj
ss = 3
else 'but if tadj is > hhu then the zone adjustment will roll back past midnight and we must change the date.
readtable mou,ddl 'get prior month end date into local day
hhl = hhu - tadj + 24
mol = mou - 1
if mou = 1 then 'Jan has to rollback to December, and year to prior
mol = 12
yyl = yyu - 1
else
if mou = 3 then 'March
spd = yyu%4
if spd <> 0 then 'not a leap year
ddl = 28
endif
if spd = 0 then 'a leap year
ddl = 29
endif
endif
endif
endif
endif
goto itsdone
itsdone:
DX = hhl/10
gosub getcode
D1 = D4
if D1 = 63 then
D1 = 0
endif
DX = hhl//10
gosub getcode
D2 = D4
DX = mm/10
gosub getcode
D3 = D4
DX = mm//10
gosub getcode
Hi2cOUT (0x00,D1, 0x00, D2, 0x00, 0x02, 0x00, D3, 0x00, D4)
Pause 100
Hi2cOUT (0x04,0x02)
If ss < 10 then
sertxd ("UTC ",#hhu,":",#mm,":0",#ss," ",#mou,"-",#ddu,"-",#yyu," PAC ",#hhl,":",#mm,":0",#ss," ",#mol,"-",#ddl,"-",#yyl,CR,LF)
else
sertxd ("UTC ",#hhu,":",#mm,":",#ss," ",#mou,"-",#ddu,"-",#yyu," PAC ",#hhl,":",#mm,":",#ss," ",#mol,"-",#ddl,"-",#yyl,CR,LF)
endif
goto Again
disptest: 'exercises display while GPS is warming up
For spd2 = 1 to 5
D1 = 1
For spd = 1 to 8
Hi2cOUT (0x00,D1, 0x00, D1, 0x00, 0x00, 0x00, D1, 0x00, D1)
D1 = D1 * 2
pause 300
Hi2cOUT (0x04,0x02) 'flash the colon
pause 300
Hi2cOUT (0x04,0x00)
next
next
Hi2cOUT (0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) 'blank disp
return
whoops:
Hi2cOUT (0x00,113, 0x00, 119, 0x00, 0x00, 0x00, 48, 0x00, 56)
SerTxd ("GPS Data Fail")
SerTxD (CR, LF)
Pause 100
GoTo Again
ledflash:
High LED
Pause 200
Low LED
Pause 200
Return
getcode:
lookup DX,(63,6,91,79,102,109,125,7,127,111,128,0,2),D4
return