• A REALLY accurate clock.

    Need to know the time - accurately for your next project?

    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.


    Code:
    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
    Note from Editor: the posts preceeding this code submission can be followed here
    This article was originally published in forum thread: A REALLY accurate clock. started by Charles Linquis View original post