Pages: [1]   Go Down
Author Topic: Arduino Ethernet Client - NTP Time Sync  (Read 4503 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Full Member
***
Karma: 1
Posts: 178
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey arduiners!

I am trying to sync my program with internet time, but unfortunately the library "Time.h" has some bugs.
The NTP ime example doesn;t work as well as every other code on the net cause of arduino version compatibility issues.

Can someon post here a working simple sketch of getting time from a server?

Thanks in advance,
    Nick Athanasoulas
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
the library "Time.h" has some bugs.
No, it has some incompatibility issues with 1.0+, all of which are solvable.

Logged

0
Offline Offline
Full Member
***
Karma: 1
Posts: 178
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Dear PaulS,
   I managed to read time but I need a better sketch so I can have date displayed too.
I also need DST (auto GMT change) everytime the GMT changes in my country.
I am willing to make the code with some help.
But is there a server that sends the local time in my country? But I want to read it as NTp...
Do you know anything to point at me, so maybe I work things out?

Nick Athanasoulas

Code:
/*
Udp NTP Client with DNS

I updated the example code to use DNS resolution from the Arduino 1.0 IDE

Basically tries to use the load-balanced NTP servers which are
  "magically" returned from DNS queries on pool.ntp.org
If DNS fails, fall back to the hardcoded IP address
  for time.nist.gov

bearpaw7 (github), 01DEC2011

This code is also in the public domain.
*/

/*

 Udp NTP Client
 
 Get the time from a Network Time Protocol (NTP) time server
 Demonstrates use of UDP sendPacket and ReceivePacket
 For more on NTP time servers and the messages needed to communicate with them,
 see http://en.wikipedia.org/wiki/Network_Time_Protocol
 
 created 4 Sep 2010
 by Michael Margolis
 modified 17 Sep 2010
 by Tom Igoe
 
 This code is in the public domain.

 */

#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include "Dns.h"

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = {  0x00, 0x00, 0xAA, 0xBB, 0xCC, 0xDD};
unsigned int localPort = 80; // local port to listen for UDP packets
IPAddress timeServer(193,92,150,3); // time.nist.gov NTP server (fallback)
const int NTP_PACKET_SIZE= 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[ NTP_PACKET_SIZE]; // buffer to hold incoming and outgoing packets
const char* host = "nsath.forthnet.gr"; // Use random servers through DNS

// A UDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
DNSClient Dns;
IPAddress rem_add;

void setup()
{
Serial.begin(9600);

// start Ethernet and UDP
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
// no point in carrying on, so do nothing forevermore:
while(true);
}
Udp.begin(localPort);
Dns.begin(Ethernet.dnsServerIP() );
}

void loop()
{
if(Dns.getHostByName(host, rem_add) == 1 ){
Serial.println("DNS resolve...");
Serial.print(host);
Serial.print("  = ");
Serial.println(rem_add);
sendNTPpacket(rem_add);
}else{
Serial.print("DNS fail...");
Serial.print("time.nist.gov = ");
Serial.println(timeServer); // fallback
sendNTPpacket(timeServer); // send an NTP packet to a time server
}
delay(1000); // wait to see if a reply is available
if ( Udp.parsePacket() ) { 
// We've received a packet, read the data from it
Udp.read(packetBuffer,NTP_PACKET_SIZE); // read the packet into the buffer

//the timestamp starts at byte 40 of the received packet and is four bytes,
// or two words, long. First, esxtract the two words:

unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]); 
// combine the four bytes (two words) into a long integer
// this is NTP time (seconds since Jan 1 1900):
unsigned long secsSince1900 = highWord << 16 | lowWord;
Serial.print("Seconds since Jan 1 1900 = " );
Serial.println(secsSince1900);

// now convert NTP time into everyday time:
Serial.print("Unix time = ");
// Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
const unsigned long seventyYears = 2208988800UL;
// subtract seventy years:
unsigned long epoch = secsSince1900 - seventyYears;
// print Unix time:
Serial.println(epoch);

// print the hour, minute and second:
Serial.print("The UTC time is "); // UTC is the time at Greenwich Meridian (GMT)
Serial.print((epoch % 86400L) / 3600); // print the hour (86400 equals secs per day)
Serial.print(':');
if ( ((epoch % 3600) / 60) < 10 ) {
// In the first 10 minutes of each hour, we'll want a leading '0'
Serial.print('0');
}
Serial.print((epoch % 3600) / 60); // print the minute (3600 equals secs per minute)
Serial.print(':');
if ( (epoch % 60) < 10 ) {
// In the first 10 seconds of each minute, we'll want a leading '0'
Serial.print('0');
}
Serial.println(epoch %60); // print the second
}
// wait ten seconds before asking for the time again
delay(10000);
Serial.println(" ");
}

// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(IPAddress& address)
{
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
packetBuffer[0] = 0b11100011;   // LI, Version, Mode
packetBuffer[1] = 0;    // Stratum, or type of clock
packetBuffer[2] = 6;    // Polling Interval
packetBuffer[3] = 0xEC;  // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;

// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:

Udp.beginPacket(address, 123); //NTP requests are to port 123
Udp.write(packetBuffer,NTP_PACKET_SIZE);
Udp.endPacket();
}

Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
But is there a server that sends the local time in my country?
No. All time servers report time in Greenwich mean time. You need to adjust for your local time.

That code does something. You want it to do something. How are those two somethings different?
Logged

0
Offline Offline
Full Member
***
Karma: 1
Posts: 178
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Its a lot of trouble to make the seconds into date according to the different days each year and some times the leap years.
I also have to customize the sketch to be able to auto-select the GMT time zone according to the date.
I maybe capture date data from another server/site and compare those ones.

 
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Its a lot of trouble to make the seconds into date according to the different days each year and some times the leap years.
I don't see why. There is, in the Time library, a function to set the time based on the number of seconds sine Jan. 1, 1970. That would be the value in epoch in the code you posted. Once you have done that, you simply call year(), month(), day(), hour(), minute(), and second().

There is a function to adjust the time. Set the time based on Greenwich mean time. Then, call adjustTime() with the offset for your local time, and let it deal with the fact that you don't live in Greenland.
Logged

0
Offline Offline
Full Member
***
Karma: 1
Posts: 178
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'll look into it. If I make it through I'll post the code. I've laready added code for GMT +/- time zones 2&3 because I am from Greece.
It's easy to adapt to any zone.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Can someone please advise how to make the date and time library to work on Arduino 1.0.1 as it gives some bug when trying to compile.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Can someone please advise how to make the date and time library to work on Arduino 1.0.1 as it gives some bug when trying to compile.
No problem. See that search bar? Use it to search for the other 50 bazillion times the question has been asked and answered.

Or search for the specific error message. I'm certain that you didn't get the Italian version of the compiler that just waves its hands and says "I can't do that".
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi, I was just working on the same thing for a few days. What I wanted is almost the same thing. Local Timezone, Date & Time and so on. Heres my code (I also included the Timezone-Library to handle the offset to NTP-UTC Time). Since I am using the 'older' Ethernet Shield with the W5100 Chip (wich has a bug), I have inserted subroutines to activate ethernet or the SD-Card. If an SD-Card is inserted at startup (when Ethernet.begin(mac) Function is called) it will fail with a DHCP-Failure, if SD-Card SS-Pin is not set to HIGH.

See my code in the attachement  smiley-cool

* NTP_Example.ino (8.11 KB - downloaded 86 times.)
Logged

Czech Republic
Offline Offline
Sr. Member
****
Karma: 3
Posts: 311
Absolute Beginner, yet.
Newbie in Arduino
since May 2013
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I am trying to sync my program with internet time
Look at this
Ways to update the RTC DS3231 from NTP server
Logged

Arduino Uno R3, Arduino Mega 2560 R3, Ethermega (R3), and some Ethernet Shields (R3), Chronodots, TMP36 sensors, DS18B20 sensors, LCDs/TFTs, RS232C to learn and play...

Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks K5CZ, as you can see I am still a beginner and this was my first working code for getting NTP-Time. I have made a few DS1307 programs, but since I don't have the correct crystal oscillator with 12.5pf my RTC is extremly inaccurate. It is a 32'768 Mhz, but not the correct pf. In order to keep my RTC accurate I attached a DCF-77 Receiver but I don't receive a signal everywhere in the house. Thats why I was making a testprogram to figure out how I can compare the RTC-Time with NTP. Thanks a lot for the link. I will verify my code again. I am always willing to learn new and better ways of coding AVR's.

Regards dragonfly
Logged

Czech Republic
Offline Offline
Sr. Member
****
Karma: 3
Posts: 311
Absolute Beginner, yet.
Newbie in Arduino
since May 2013
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm still a beginner too :-) I posted my latest version of the program in the topic above.
Logged

Arduino Uno R3, Arduino Mega 2560 R3, Ethermega (R3), and some Ethernet Shields (R3), Chronodots, TMP36 sensors, DS18B20 sensors, LCDs/TFTs, RS232C to learn and play...

Pages: [1]   Go Up
Jump to: