/* * Time_NTP.pde * Example showing time sync to NTP time source * * Also shows how to handle DST automatically. * * This sketch uses the EtherCard library: * http://jeelabs.org/pub/docs/ethercard/ */ #include #include byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // NTP Server const char timeServer[] PROGMEM = "pool.ntp.org"; const int utcOffset = 1; // Central European Time //const int utcOffset = -5; // Eastern Standard Time (USA) //const int utcOffset = -4; // Eastern Daylight Time (USA) //const int utcOffset = -8; // Pacific Standard Time (USA) //const int utcOffset = -7; // Pacific Daylight Time (USA) // Packet buffer, must be big enough to packet and payload #define BUFFER_SIZE 550 byte Ethernet::buffer[BUFFER_SIZE]; const unsigned int remotePort = 123; void setup() { Serial.begin(9600); while (!Serial) // Needed for Leonardo only ; delay(250); Serial.println("TimeNTP_ENC28J60 Example"); if (ether.begin(BUFFER_SIZE, mac) == 0) { // no point in carrying on, so do nothing forevermore: while (1) { Serial.println("Failed to access Ethernet controller"); delay(10000); } } if (!ether.dhcpSetup()) { // no point in carrying on, so do nothing forevermore: while (1) { Serial.println("Failed to configure Ethernet using DHCP"); delay(10000); } } ether.printIp("IP number assigned by DHCP is ", ether.myip); Serial.println("waiting for sync"); //setSyncProvider(getNtpTime); // Use this for GMT time setSyncProvider(getDstCorrectedTime); // Use this for local, DST-corrected time } time_t prevDisplay = 0; // when the digital clock was displayed void loop() { if (timeStatus() != timeNotSet) { if (now() != prevDisplay) { //update the display only if time has changed prevDisplay = now(); digitalClockDisplay(); } } } void digitalClockDisplay(){ // digital clock display of the time Serial.print(hour()); printDigits(minute()); printDigits(second()); Serial.print(" "); Serial.print(day()); Serial.print(" "); Serial.print(month()); Serial.print(" "); Serial.print(year()); Serial.println(); } void printDigits(int digits){ // utility for digital clock display: prints preceding colon and leading 0 Serial.print(":"); if(digits < 10) Serial.print('0'); Serial.print(digits); } /*-------- NTP code ----------*/ // SyncProvider that returns UTC time time_t getNtpTime() { // Send request Serial.println("Transmit NTP Request"); if (!ether.dnsLookup(timeServer)) { Serial.println("DNS failed"); return 0; // return 0 if unable to get the time } else { //ether.printIp("SRV: ", ether.hisip); ether.ntpRequest(ether.hisip, remotePort); // Wait for reply uint32_t beginWait = millis(); while (millis() - beginWait < 1500) { word len = ether.packetReceive(); ether.packetLoop(len); unsigned long secsSince1900 = 0L; if (len > 0 && ether.ntpProcessAnswer(&secsSince1900, remotePort)) { Serial.println("Receive NTP Response"); return secsSince1900 - 2208988800UL; } } Serial.println("No NTP Response :-("); return 0; } } /* Alternative SyncProvider that automatically handles Daylight Saving Time (DST) periods, * at least in Europe, see below. */ time_t getDstCorrectedTime (void) { time_t t = getNtpTime (); if (t > 0) { TimeElements tm; breakTime (t, tm); t += (utcOffset + dstOffset (tm.Day, tm.Month, tm.Year + 1970, tm.Hour)) * SECS_PER_HOUR; } return t; } /* This function returns the DST offset for the current UTC time. * This is valid for the EU, for other places see * http://www.webexhibits.org/daylightsaving/i.html * * Results have been checked for 2012-2030 (but should work since * 1996 to 2099) against the following references: * - http://www.uniquevisitor.it/magazine/ora-legale-italia.php * - http://www.calendario-365.it/ora-legale-orario-invernale.html */ byte dstOffset (byte d, byte m, unsigned int y, byte h) { // Day in March that DST starts on, at 1 am byte dstOn = (31 - (5 * y / 4 + 4) % 7); // Day in October that DST ends on, at 2 am byte dstOff = (31 - (5 * y / 4 + 1) % 7); if ((m > 3 && m < 10) || (m == 3 && (d > dstOn || (d == dstOn && h >= 1))) || (m == 10 && (d < dstOff || (d == dstOff && h <= 1)))) return 1; else return 0; }