The code below allows your PIC to log into a network timeserver and it (eventually) writes the time to a Dallas RTC (code not supplied).
The PIC checks the NET TIME every power-up and thereafter every 4 hours. If it doesn't make connection, it tries an alternate time server. If THAT doesn't work (after retries) it gives up and tries again 4 hours later. A Lantronix XPort handles the connection to the net.
The PIC normally reads the time from the Dallas RTC. The clock is self-setting and self-correcting, as long as you have a network connection.
And all of you using 16F chips, time to upgrade! This sub requires LONGS.
Net Time' is the number of seconds since Jan 1 1900 This sub accomodates for leap years, GMT offsets and Daylight Savings Time. The sub assumes you are in the present century, so it takes a shortcut by pre-subtracting the number of seconds from Jan 1 1900 to Jan 1 2009. It should be self-explanatory. |
Hoffset is the hours offset from GMT Sign = "1" or "2" depending on whether you are earlier or later than GMT DST = 1 if you are in Daylight Savings Time (Another part of the PGM changes that value when appropriate). GETNETTIME: NETRETRYCOUNT = 0 GETNETTIME2: HSEROUT [13,10,"TIMESERVER ",#TSIP1,".",#TSIP2,".",#TSIP3,".",#TSIP4,13,10] PAUSE 100 THEADER[0] = $2 ' STX THEADER[1] = TSIP1 ' DESTINATION IP THEADER[2] = TSIP2 THEADER[3] = TSIP3 THEADER[4] = TSIP4 THEADER[5] = 0 ; DESTINATION PORT HIGHBYTE THEADER[6] = 123 ; DESTINATION PORT LOWBYTE LRC1 = 0 LRC2 = 0 For X = 1 to 6 LRC1 = LRC1 ^ THeader[x] next X THEADER[7] = LRC1 THEADER[8] = 0 THEADER[9] = 48 'Data Length lowbyte ;Send the header HSEROUT [13,10] For X = 0 to 9 HSEROUT2 [THeader[X]] Next X LRC2 = LRC2 ^ THeader[8] LRC2 = LRC2 ^ THeader[9] ;Send the data HSEROUT2 [$1B] LRC2 = LRC2 ^ $1B For X = 0 To 46 HSEROUT2 [0] LRC2 = LRC2 ^ 0 NEXT X ;Send the Checksum (LRC) HSEROUT2 [LRC2] getresponse: HSERIN2 1000,NoResponse,[Wait($2)] hserin2 200,NoResponse,[SKIP 41,TimeNow.Byte3,TimeNow.Byte2,TimeNow.Byte1,TimeNow.Byte0] READ 851,HOFFSET IF sign = "1" then if DST = 1 and HOffset = 0 THEN Sign = "2" GOTO OtherSide ENDIF TimeNow = Timenow - ((HOffset - DST) * 3600) ENDIF OtherSide: IF Sign = "2" THEN TimeNow = TimeNow + ((Hoffset + DST) * 3600) ENDIF SINCEJAN2009 = TIMENOW - 3439756800 ; 3439756800 is the #of sec from Jan1 1900 to Jan1 2009 RUNNINGSECONDS = SINCEjAN2009 YR = 2009 GETYEAR: LEAP = (YR//4) ; = 0 if leap year if LEAP = 0 then SecondsInYear = 31622400 ;366*60*60**24 ELSE SecondsInYear = 31536000 ;365*60*60*24 endif If RunningSeconds > SecondsInYear Then RunningSeconds = RunningSeconds - SecondsInyear YR = YR + 1 GOTO GetYear ENDIF Mo = 1 ; Start with Month = 1 GETMONTH: IF LEAP > 0 THEN lookup2 MO,[0,2678400,2419200,2678400,2592000,2678400,2592000,2678400,2678400,2592000,2678400,2592000,2678400],SecondsInMonth ELSE LOOKUP2 MO,[0,2678400,2505600,2678400,2592000,2678400,2592000,2678400,2678400,2592000,2678400,2592000,2678400],SecondsInMonth ENDIF If RunningSeconds >= SecondsInMonth THEN RunningSeconds = RunningSeconds - SecondsInMonth MO = MO + 1 GOTO GETMONTH ENDIF FINDDAYS: DA = RUNNINGSECONDS/86400 RUNNINGSECONDS = RUNNINGSECONDS//86400 HR = RUNNINGSECONDS/3600 RUNNINGSECONDS = RUNNINGSECONDS//3600 MN = RUNNINGSECONDS/60 RUNNINGSECONDS = RUNNINGSECONDS//60 SC = RUNNINGSECONDS Da = Da + 1 HSEROUT [13,10,13,10,DEC2 HR,":",DEC2 MN,":",DEC2 SC," ",DEC2 MO,"/",DEC2 DA,"/",#YR,13,10] Return
Re: SERIN2 Receiving Wrong Data
The sending device has the typical 18F4550 USB setup and it is set to "Define OSC 48". The receiving device is set to "DEFINE OSC 16".
rsocor01 Yesterday, 19:56