neiltechspec
Senior Member
Many of my projects use RTC Clock Modules, either DS1307's or DS3231's.
I got fed up with try to set the time from the PC and could only get within 3 or 4 secs, so came up with this today.
Uses a ublox NEO-6 GPS Module PICAXE 28X2. Needs an X1 or X2 chip for the bit shifting capabilities (maybe possible on a M2 series but I couldn't work out how).
Using GPS strings - GPRMC, GPGGA & GPZDA, at the push of a button, if Sat Lock is ok, writes the time & date (time in GMT) to the RTC module.
Time is set within half a second accuracy or better I reckon.
Neil.
I got fed up with try to set the time from the PC and could only get within 3 or 4 secs, so came up with this today.
Uses a ublox NEO-6 GPS Module PICAXE 28X2. Needs an X1 or X2 chip for the bit shifting capabilities (maybe possible on a M2 series but I couldn't work out how).
Using GPS strings - GPRMC, GPGGA & GPZDA, at the push of a button, if Sat Lock is ok, writes the time & date (time in GMT) to the RTC module.
Time is set within half a second accuracy or better I reckon.
Neil.
Code:
#rem
This program sets a DS1307 or DS3231 using a GPS clock source.
Needs an X1 or X2 PICAXE for shifting bits left capability.
Initial Version 1.0, August 2014
Ublox NEO-6 set to output @ 9600 baud the following messages :-
$GPRMC,164757.00,A,5234.07991,N,00149.09098,W,0.400,,250714,,,A*67
$GPVTG,,T,,M,0.400,N,0.741,K,A*25
$GPGGA,164757.00,5234.07991,N,00149.09098,W,1,11,1.52,130.6,M,47.9,M,,*42
$GPGLL,5234.07991,N,00149.09098,W,164757.00,A,A*7F
$GPZDA,164757.00,25,07,2014,00,00*67
pin A.0 is OLED / LCD display
pin B.0 is BST switch (active high)
pin A.1 is TTL serial in from GPS Module @ 9600,8,n,1
pin A.3 is TTL serial out to GPS Module (not used)
pin C.0 is LED - 330R to 0v
pin C.1 is RTC set button (active low)
pin C.2 is true TTL serial out @ 9600,8,n,1 (for Serial to IP)
pin C.3 is I2C scl for RTC
pin C.4 is I2C sda for RTC
#endrem
#picaxe 28X2
#no_data
#terminal 19200
symbol seconds = b20
symbol mins = b21
symbol hour = b22
symbol day = b23
symbol date = b24
symbol month = b25
symbol year = b26
symbol control = b27
symbol oled = A.0
symbol GPSin = A.1
symbol IPout = C.2
symbol dbaud = N2400_16 ;display baudrate
symbol iobaud = T9600_16 ;I/O baudrate
Init:
pullup %00000001 ;enable pullup on port B.0 for BST switch (only port B has pullup capability)
setfreq m16 ;runs at 16Mhz for reliable capture @ 9600 baud
pause 12000 ;3sec pause for LCD Display init
serout oled,dbaud,(254,1) ;clear display
pause 200 ;50ms pause
hi2csetup i2cmaster, %11010000, i2cslow_16, i2cbyte ;set RTC slave address
Main:
do
serin GPSin,iobaud,("$GPRMC,"),b1,b2,b3,b4,b5,b6,b7,b7,b7,b7,b7
serin GPSin,iobaud,("$GPGGA,"),b8,b8,b8,b8,b8,b8,b8,b8,b8,b8,b8,b8,b8,b8,b8,b8,b8,b8,b8,b8,b8,b8,b8,b8,b8,b8,b8,b8,b8,b8,b8,b8,b8,b8,b8,b8,b8,b8,b8,b8,b9
serin GPSin,iobaud,("$GPZDA,"),b10,b10,b10,b10,b10,b10,b10,b10,b10,b10,b10,b11,b12,b13,b14,b15,b16,b17,b18,b19
if b7="V" then ;gps rx data not locked
high C.0 ;turn on LED
serout oled,dbaud,(254,192,"No Sat Lock ")
serout IPout,iobaud,("No Sat Lock",cr,lf)
sertxd("No Sat Lock",cr,lf,cr,lf)
endif
if pinC.1 <> 1 and b7="A" then
gosub Set_RTC
endif
sertxd("GPS time: ",b1,b2,":",b3,b4,":",b5,b6," GMT",cr,lf)
if pinB.0=1 then
gosub BST
endif
serout oled,dbaud,(254,128,b1,b2,":",b3,b4,":",b5,b6) ;GPS Time, GMT or BST
serout IPout,iobaud,(b1,b2,":",b3,b4,":",b5,b6,cr,lf)
if b7="A" then ;if sat lock ok, show date, lat, long & No of Sat's
low C.0
pulsout C.0,400 ;flash LED on C.0
serout oled,dbaud,(254,138,b10,b11,"/",b13,b14,"/",b16,b17,b18,b19) ;GPS date
serout IPout,iobaud,(b10,b11,"/",b13,b14,"/",b16,b17,b18,b19,cr,lf)
sertxd("GPS Date: ",b10,b11,"/",b13,b14,"/",b16,b17,b18,b19,cr,lf)
serout oled,dbaud,(254,192,"Sat's: ",b8,b9) ;Sat's tracked
serout IPout,iobaud,("Sat's: ",b8,b9,cr,lf)
calibadc10 w24
w20 = 10486/w24
bintoascii w20,b42,b43,b44
serout oled,dbaud,(254,201," Batt: ",b43,".",b44,"v")
serout IPout,iobaud,("Batt: ",b43,".",b44,"v",cr,lf,cr,lf)
endif
gosub RTC
loop
RTC:
hi2cin $0,(seconds,mins,hour,day,date,month,year)
bcdtoascii seconds,b30,b31
bcdtoascii mins,b32,b33
bcdtoascii hour,b34,b35
bcdtoascii date,b36,b37
bcdtoascii month,b38,b39
bcdtoascii year,b40,b41
serout oled,dbaud,(254,148,"RTC Date & Time GMT")
if b30 = "?" then
serout oled,dbaud,(254,212,"RTC Module not Found")
sertxd("RTC Module not Found",cr,lf)
return
endif
serout oled,dbaud,(254,212,b34,b35,":",b32,b33,":",b30,b31) ;RTC Time
sertxd("RTC Time: ",b34,b35,":",b32,b33,":",b30,b31," GMT",cr,lf)
serout oled,dbaud,(254,220," ",b36,b37,"/",b38,b39,"/20",b40,b41) ;RTC Date
sertxd("RTC Date: ",b36,b37,"/",b38,b39,"/20",b40,b41,cr,lf,cr,lf)
return
Set_RTC:
serout oled,dbaud,(254,192,"*** Setting RTC *** ")
let b5 = b5 -48 ;secs tens
let b6 = b6 -48 ;secs units
let b3 = b3 -48 ;mins tens
let b4 = b4 -48 ;mins units
let b1 = b1 -48 ;hours tens
let b2 = b2 -48 ;hours units
let b10 = b10 -48 ;date tens
let b11 = b11 -48 ;date units
let b13 = b13 -48 ;month tens
let b14 = b14 -48 ;month units
let b18 = b18 -48 ;year tens
let b19 = b19 -48 ;year units
let seconds = b5 << 4 + b6
let mins = b3 << 4 + b4
let hour = b1 << 4 + b2
let day = $01 ;01 day of week (not used by me)
let date = b10 << 4 + b11
let month = b13 << 4 + b14
let year = b18 << 4 + b19
let control = %00010000 ;Enable output at 1Hz
hi2cout 0,(seconds,mins,hour,day,date,month,year,control)
pause 4000 ;1sec pause
serout oled,dbaud,(254,1) ;clear display
pause 200 ;50ms pause
goto main
BST:
inc b2 ;add 1 to b2 value
if b2=58 then let B2=48 inc b1 endif ;if b2 > "9", set it to "0" and add 1 to b1
if b1=50 and b2=52 then let b1=48 b2=48 endif ;if b1="2" and b2="4", set them both to "0"
return