Jump to content
  • 0

SNTP


pappastech

Question

I'm trying to figure out how to use the SNTP functionality built into the DEIPcK library, but cannot find an example anywhere. Does anyone have an example of how to use this part of the library?

Based on my review of the SNTP library itself, it appears that I'll need to call SNTPv4Init followed by a call to either SNTPv4GetNTPEpochTime or SNTPv4GetUNIXEpochTime to get real time, which can be used to configure an RTC to continue to keep track of time. But I don't understand all the arguments that these functions require to be able to use them.

Thanks in advance for any example code anyone is willing to share.

Tom

Link to comment
Share on other sites

10 answers to this question

Recommended Posts

Hi @pappastech,

I heard back from our engineer and learned the following:

<start>
He is going too low in the network stack.
 
He should call…
 
unsigned long secondsSinceEpoch(void);
Or
unsigned long secondsSinceEpoch(IPSTATUS * pStatus);
 
#define ipsTimeSincePowerUp         MakeDEIPcKStatus(20)
#define ipsTimeSinceEpoch           MakeDEIPcKStatus(21)
 
The first call to secondsSinceEpoch will do the SNTP calls in the background; which will take some time, milliseconds. The status returned before the time is set is ipsTimeSincePowerUp, once the time is obtained the status will be ipsTimeSinceEpoch.
 
Some sample code.
 
You have to wait for the time to become valid, so check the status.
 
        epochTime = deIPcK.secondsSinceEpoch(&status);
        if(status == ipsTimeSinceEpoch)
        {
            GetDayAndTime(epochTime, szTemp);
            Serial.println(szTemp);
        }
<end>
Let me know if you have any questions.
 
Thank you,
JColvin
Link to comment
Share on other sites

18 hours ago, JColvin said:

Hi @pappastech,

I heard back from our engineer and learned the following:

<start>
He is going too low in the network stack.
 
He should call…
 
unsigned long secondsSinceEpoch(void);
Or
unsigned long secondsSinceEpoch(IPSTATUS * pStatus);
 
#define ipsTimeSincePowerUp         MakeDEIPcKStatus(20)
#define ipsTimeSinceEpoch           MakeDEIPcKStatus(21)
 
The first call to secondsSinceEpoch will do the SNTP calls in the background; which will take some time, milliseconds. The status returned before the time is set is ipsTimeSincePowerUp, once the time is obtained the status will be ipsTimeSinceEpoch.
 
Some sample code.
 
You have to wait for the time to become valid, so check the status.
 
        epochTime = deIPcK.secondsSinceEpoch(&status);
        if(status == ipsTimeSinceEpoch)
        {
            GetDayAndTime(epochTime, szTemp);
            Serial.println(szTemp);
        }
<end>
Let me know if you have any questions.
 
Thank you,
JColvin

Perfect.

Thank you!

Link to comment
Share on other sites

I've tried to implement this is a test sketch, but the status returned from secondsSinceEpoch never changes. Here is the code I have now to see if status would ever change...

epochTime = deIPcK.secondsSinceEpoch( &status );
while ( status != ipsTimeSinceEpoch )
{
Serial.println( "Waiting..." );
}
Serial.println( "EpochTime: " );
Serial.println( epochTime );

'Waiting...' is continuously printed to the console; I turned it off after 20 seconds. What am I doing incorrectly here?

Link to comment
Share on other sites

Hi @pappastech,

The big thing that you will need to ensure is that you are connected to the internet with your board, otherwise you will never connect to a time server. The deWebIOServer under the HTTPServer example connects you to a WiFi network (after you change the the username and password in the HTTPServerConfig.h file, explained more in this tutorial here), though I am still working on getting the secondsSinceEpoch function working in that particular demo.

Thanks,
JColvin

Link to comment
Share on other sites

Hi @pappastech.

I got it working with the deWebIOServer in the Arduino IDE 1.6.9.

In the deWebIOServerSrc.cpp file that opens up with the HTTPServer example, I adjusted the loop function to say the following:

 unsigned long status = 0;
 unsigned long epochTime = 0;
void loop(void) 
{
    // process the HTTP Server
    ProcessServer();
    epochTime = deIPcK.secondsSinceEpoch( &status );
  if ( status != ipsTimeSinceEpoch )
    {
    //do nothing since it'll be printing for awhile while everything gets connected
    }
  else{
    Serial.print( "EpochTime: " );
    Serial.println( epochTime );
  }
}

Let me know if you have any questions.

Thanks,
JColvin

Link to comment
Share on other sites

22 hours ago, JColvin said:

Hi @pappastech.

I got it working with the deWebIOServer in the Arduino IDE 1.6.9.

In the deWebIOServerSrc.cpp file that opens up with the HTTPServer example, I adjusted the loop function to say the following:


 unsigned long status = 0;
 unsigned long epochTime = 0;
void loop(void) 
{
    // process the HTTP Server
    ProcessServer();
    epochTime = deIPcK.secondsSinceEpoch( &status );
  if ( status != ipsTimeSinceEpoch )
    {
    //do nothing since it'll be printing for awhile while everything gets connected
    }
  else{
    Serial.print( "EpochTime: " );
    Serial.println( epochTime );
  }
}

Let me know if you have any questions.

Thanks,
JColvin

I had 2 issues with my code.

1. I didn't have the status variable set to the correct type.

2. My while loop doesn't have a call to DEIPcK::periodicTasks(), so the code gets stuck in the while loop and never completes the SNTP initialization.

I've been able to get it working now.

Thanks for the help.

Link to comment
Share on other sites

One more question actually, how can I specify a custom list of NTP servers without changing the default list contained in SNTPv4.h? There appears to be a path through SNTPv4Init, but is this the right place to do it?

The higher level definitions in DEIPcK.cpp and deIP.h seem to pass NULL for the server parameter provided by SNTPv4Init.

Link to comment
Share on other sites

HI @pappastech,

I talked with our engineer and learned that there isn't a true and tested way to do this as the library was intended for the chipKIT/Arduino crowd, so the full functionality of the stack was not exposed to the deIP layer. What he recommended for what you are looking for is the following:

//before calling
DEIPcK::secondsSinceEpoch(IPSTATUS * pStatus)
 
//if he calls
 
                // define his list of servers.
uint8_t const * const rgHisNTPServers[] = {(uint8_t const * const) "0.us.pool.ntp.org", (uint8_t const * const) "1.us.pool.ntp.org", (uint8_t const * const) "2.us.pool.ntp.org", (uint8_t const * const) "3.us.pool.ntp.org"};
 
                // then init the SNTP application
SNTPv4Init(_LLGetDefaultAdaptor(), rgbSNTPv4Mem, SNTPv4MemSize, hDhcpDnsNtpPMGR, rgHisNTPServers,sizeof( rgHisNTPServers)/sizeof(uint8_t *), NULL);
 
                // then call
deIPcK.secondsSinceEpoch(IPSTATUS * pStatus);

However, his final note about this is "Untested, never tried, good luck", so be aware that we will be of limited help in terms of providing further functionality for SNTP within the DEIPck library that isn't already built in. I can try to provide some additional help, but I am personally not versed in this WiFi stack so I will be of limited help.

Thanks,
JColvin

Link to comment
Share on other sites

3 hours ago, JColvin said:

HI @pappastech,

I talked with our engineer and learned that there isn't a true and tested way to do this as the library was intended for the chipKIT/Arduino crowd, so the full functionality of the stack was not exposed to the deIP layer. What he recommended for what you are looking for is the following:


//before calling
DEIPcK::secondsSinceEpoch(IPSTATUS * pStatus)
 
//if he calls
 
                // define his list of servers.
uint8_t const * const rgHisNTPServers[] = {(uint8_t const * const) "0.us.pool.ntp.org", (uint8_t const * const) "1.us.pool.ntp.org", (uint8_t const * const) "2.us.pool.ntp.org", (uint8_t const * const) "3.us.pool.ntp.org"};
 
                // then init the SNTP application
SNTPv4Init(_LLGetDefaultAdaptor(), rgbSNTPv4Mem, SNTPv4MemSize, hDhcpDnsNtpPMGR, rgHisNTPServers,sizeof( rgHisNTPServers)/sizeof(uint8_t *), NULL);
 
                // then call
deIPcK.secondsSinceEpoch(IPSTATUS * pStatus);

However, his final note about this is "Untested, never tried, good luck", so be aware that we will be of limited help in terms of providing further functionality for SNTP within the DEIPck library that isn't already built in. I can try to provide some additional help, but I am personally not versed in this WiFi stack so I will be of limited help.

Thanks,
JColvin

Thank you for the help JColvin. Given the licenses for this code are BSD and MIT, I will likely just modify the library to allow outside configuration of this list of NTP servers.

Much appreciated,

Tom

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...