NTP server / External (no "www") time base for PC / DCF77


Closed Thread
Results 1 to 13 of 13

Hybrid View

  1. #1
    Join Date
    Aug 2006
    Location
    SWITZERLAND (french speaking)
    Posts
    891

    Default NTP server / External (no "www") time base for PC / DCF77

    Hi there,

    I have built a DCF77 receiver (http://www.ptb.de/en/org/4/44/442/dcf77_1_e.htm) I'd like to use as a time base server in a "private" LAN (= no connection to www).

    As my programming skills are modest, I don't know how to create a NTP software. All I could reach, is a simple DELPHI based tool that will update the PC's internal clock via TIME and DATE DOS commands. I grab the receiver's data via the COM port.

    I had a look at this kind of module http://www.connectone.com/products.asp?did=73&pid=93 that might be of any help. But what about the sofware?
    Roger

  2. #2
    Join Date
    Jan 2005
    Location
    Boston MA
    Posts
    19

    Default

    NTP on port 123 is going to be a LOT to work on. If you have needs for VERY high accuracy it's what you use. Commercial NTP time servers are in the $2K range See:
    http://www.ntp.org/
    SNTP is easier to deal with (this is what your PC uses to sync up)
    http://www.micro-examples.com/public...nal-clock.html (the code for this is over 1K lines)
    Time Server on port 37 is easier
    http://www.codeproject.com/KB/IP/udptime.aspx
    DayTime server on port 13 is even simpler

    I would start your efforts programming a Time Server client using a PIC ENC28J60. Once you get a little background and practice start working on the server.

    As far a I know no big company ever made a 60/77khz NTP server. There is too much phase shift every day. Most people use GPS as a source for an NTP server. However a 77Khz time source would make a good backup.

    I expect to work on such a project down the road but I will probably use something with a little more power like an Ethernut http://www.ethernut.de/en/index.html They have an example of a SNTP client that is less than 200 lines but written in C code.

    Regards
    Tim

  3. #3
    Join Date
    Sep 2005
    Location
    Campbell, CA
    Posts
    1,107

    Default

    I wrote a routine that 'calls' a timeserver on port 123 (UDP protocol). It uses a Lantronix XPort as the network interface.

    The routine calculates current time based on NET TIME (number of seconds elapsed since 00:00:00,Jan 1, 1900). It allows input of time zone and DST flag. It doesn't automatically calculate when DST begins/ends, but it does take DST into account. Leap years, too.

    It shows the current time and then writes the values into a DS1307.

    If someone is interested, I'll post.
    Charles Linquist

  4. #4
    Join Date
    Aug 2008
    Location
    Portugal
    Posts
    240

    Default

    Quote Originally Posted by Charles Linquis View Post
    I wrote a routine that 'calls' a timeserver on port 123 (UDP protocol). It uses a Lantronix XPort as the network interface.

    The routine calculates current time based on NET TIME (number of seconds elapsed since 00:00:00,Jan 1, 1900). It allows input of time zone and DST flag. It doesn't automatically calculate when DST begins/ends, but it does take DST into account. Leap years, too.

    It shows the current time and then writes the values into a DS1307.

    If someone is interested, I'll post.
    Hi, i'm interested in your project. Can you post the code, please?

    Thanks
    Thanks and Regards;
    Gadelhas

  5. #5
    Join Date
    Sep 2005
    Location
    Campbell, CA
    Posts
    1,107

    Default

    It might take a bit of explanation, but -

    The code below is sent after the XPort is initialized for UDP.

    Hoffset is number of hours before or after GMT.
    SIGN is earlier ("1") or later ("2") than GMT.
    The code works only with 18F chips because it uses PBPL.




    Code:
    GETNETTIME:
           
           
           
           NETRETRYCOUNT = 0
           GOSUB INTDISABLE
           
    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]
              
                    
             
    '             TIME1900_2009 = 3439756800
    
              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   ; Because there is no day zero
    
                   HSEROUT [13,10,13,10,DEC2 HR,":",DEC2 MN,":",DEC2 SC,"   ",DEC2 MO,"/",DEC2 DA,"/",#YR,13,10] 
    
                   YR8 = YR - 2000 ; clock only takes two digits! 
                    
    ConverttoBCD:             
                   DT = (DA/10) << 4 + (DA//10)
                   YR8 = (YR8/10) << 4 + (YR8//10)
                   MN = (MN/10) << 4 + (MN//10)
                   SC = (SC/10) << 4 + (SC//10)
                   HR = (HR/10) << 4 + (HR//10)
                   MO = (MO/10) << 4 + (MO//10)
                   gosub CLOCKWRITE
                   NetFail = 0
                   HSEROUT ["CLK updated",13,10]
                    pause 2000
                  goto DoneClock
              
                     
    NoResponse: 
                   hserout ["RETRYING GetNetTime",13,10]
                     pause 1000
                     
                     NETRETRYCOUNT = NETRETRYCOUNT + 1 
                     
                     if NETRETRYCOUNT < 5 THEN 
                        goto getnettime2
                     ENDIF
                     IF NETRETRYCOUNT < 10 THEN
                        GOSUB GETALTERNATESERVER
                        goto getnettime2
                     ENDIF
                     
                        READ 800,Dummy
                        TSIP1 = Dummy
                        THEADER[1] = TSIP1  'Set it back to primary
                        READ 801,Dummy
                        TSIP2 = Dummy
                        THEADER[2] = TSIP2
                        READ 802,Dummy
                        TSIP3 = Dummy
                        THEADER[3] = TSIP3
                        READ 803,Dummy
                        TSIP4 = Dummy
                        THEADER[4] = TSIP4
                        NetFail = 1
                     HSEROUT [13,10,"FAILED NET TIME",13,10]
         
    DoneClock:                 
             
             GOSUB INTREENABLE  
             
             RETURN
    Charles Linquist

  6. #6
    Join Date
    Dec 2005
    Posts
    1,073

    Thumbs up

    Thanks, Charles. I've been planning to write a similar procedure although I 'm using a different ethernet adapter (WIZ110SR), different RTC (ST M41T81) and different processor (ZBasic ZX40p). Still, adapting your code should save me a lot of time and error.

    BTW, I've also used the ConnectOne nano LanReach mentioned by the OP. It has a very attractive price, easy communication protocol (patterned after modem AT commands) and a nice set of Internet protocols (e.g. SMTP/POP3 for email which are much easier to use than Lantronix). Unfortunately, Mouser will not ship it outside the USA due to Homeland Security issues.

    Also, Tibbo (http://tibbo.com/products/) has several ethernet-serial adapters some of which can be programmed in their Basic dialect. They have source examples for email, SNTP, etc. on their website. Unfortunately, their XPort like versions are not sold in the USA (I suspect because of Lantronix patents).
    Last edited by dhouston; - 30th October 2010 at 12:21.

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts