Thread: NTP_time struggels

  1. #1
    Registered User
    Join Date
    Sep 2011
    Posts
    52

    NTP_time struggels

    Dear users,

    [platform: Ubuntu]

    I have a program witch collect information from a solar inverter. The C program makes a json data file, and a shell script send this to a server with a curl command.
    It all works fine, until I tried to insert NTP_timestamps. My timer is to fast. (in no time i posted on 12 december)

    I made a script witch called a C program [see below], and after that it called ntptime -r. (than a then seconds sleep) this was all in a while(1), so I could find out what the diffrence was. The code:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <time.h>
    #include <fcntl.h>
    #include <sys/timex.h>
    
    int main()
    {
    	long int i=0;
    	srand(time(NULL));
    	struct ntptimeval start;
    	while(1)
    	    {
    	    ntp_gettime(&start);
    	    i=start.time.tv_sec;
    	    printf("i is %lu\r\n",i);
    	    system("ntptime");
    	    sleep(10);
    	    }
    
    return 0;
    }
    when I take the output and make them both decimal, i get this:

    1530672002 8670001000 = 1354884676
    1530672007 1640517000 = 1354884686
    1530672015 7581455000 = 1354884706
    The first 2 numbers have a relation 1 to 2 (7-2=5, 86-76=10,)
    When we take the thirt number, we get a other relation! (15-7=8, 06-86= 20, so we get 1 to 2.5)
    How can this be? help! The endgoal is to get the left number.

    Kind regards,

    Libpgeak

  2. #2
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Run over that "the endgoal is to get the left number", part. Not clear.

    If you want more evenly spaced timestamps, then I wouldn't use outside resources requiring a call to system, and I wouldn't use sleep(10) either. When you use these things, control is passed over to the OS, and will be done according to the OS scheduler, instead of the timing you may want.

    If you want to use sleep(), set it for 3/4ths the value you really want, and use logic that leaves the loop when you reach a certain time for the finer control - when newtime > oldtime + pause, break; kind of logic.

    If I'm way off here, run over that description again.

  3. #3
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    I think your assumptions are wrong.

    Try these changes, and see if it dawns on you:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <time.h>
    #include <fcntl.h>
    #include <sys/timex.h>
    
    int main(void)
    {
        struct ntptimeval start;
        struct timeval    now;
        unsigned long     ntp_s, ntp_us;
    
        while(1)
        {
    
            gettimeofday(&now, NULL);
    
            start.tai = 0L;
            start.time.tv_sec = 0L;
            start.time.tv_usec = 0L;
            ntp_gettime(&start);
    
            /* Calculate NTP time - the epoch difference is 2208988800 seconds. */
            ntp_s = (unsigned long)now.tv_sec + 2208988800L;
            ntp_us = (unsigned long)now.tv_usec;
    
            printf("NTP: %.6f\n", (double)start.time.tv_sec + (double)start.time.tv_usec / 1000000.0);
            printf("Now: %.6f\n", (double)now.tv_sec + (double)now.tv_usec / 1000000.0);
            printf("NTP epoch: %08lx.%08lx\n", ntp_s, ntp_us);
    
            fflush(stdout);
    
            system("ntptime");
    
            sleep(10);
        }
    
        return 0;
    }
    If it is not yet clear to you, let me spell it out:

    Use gettimeofday() or clock_gettime(). Note that the latter uses nanoseconds (9 digits), not microseconds (6 digits) like the former and NTP do. Add exactly 2208988800 seconds to change from the Unix epoch to NTP epoch.

    For me, ntp_gettime() returns nonsense (actually, nanoseconds instead of microseconds in the tv_usec field, confusing the output, and causing a random difference to the actual time), but the system clock is synchronized to NTP. That is because I have the NTP daemon running, synchronizing to nearby NTP pool servers: see pool.ntp.org for example. This is exactly what you should do, too.
    Last edited by Nominal Animal; 12-08-2012 at 03:07 AM.

  4. #4
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    The C program makes a json data file, and a shell script send this to a server with a curl command.
    Why wouldn't you just use libcurl and do it all from one program?

  5. #5
    Registered User
    Join Date
    Sep 2011
    Posts
    52
    @rags_to_riches Becouse this is the most easy and moddable way.

  6. #6
    Registered User
    Join Date
    Sep 2011
    Posts
    52
    I found out what the problem was: the NTP timestamp is 64 bits. So you need a long long unsigned int. Then you take the time, and add the 2208988800. after this, bitshift 32 places and done!

Popular pages Recent additions subscribe to a feed

Tags for this Thread