From e4cf2261fdefa080f68176495b7d73ce02929eab Mon Sep 17 00:00:00 2001 From: SukkoPera Date: Mon, 29 Aug 2016 22:24:22 +0200 Subject: [PATCH] Add TimeNTP_ENC28J60 example --- .../TimeNTP_ENC28J60/TimeNTP_ENC28J60.ino | 168 ++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 examples/TimeNTP_ENC28J60/TimeNTP_ENC28J60.ino diff --git a/examples/TimeNTP_ENC28J60/TimeNTP_ENC28J60.ino b/examples/TimeNTP_ENC28J60/TimeNTP_ENC28J60.ino new file mode 100644 index 0000000..b6ad796 --- /dev/null +++ b/examples/TimeNTP_ENC28J60/TimeNTP_ENC28J60.ino @@ -0,0 +1,168 @@ +/* + * 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; +} +