PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

169 lines
4.4KB

  1. /*
  2. * Time_NTP.pde
  3. * Example showing time sync to NTP time source
  4. *
  5. * Also shows how to handle DST automatically.
  6. *
  7. * This sketch uses the EtherCard library:
  8. * http://jeelabs.org/pub/docs/ethercard/
  9. */
  10. #include <TimeLib.h>
  11. #include <EtherCard.h>
  12. byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
  13. // NTP Server
  14. const char timeServer[] PROGMEM = "pool.ntp.org";
  15. const int utcOffset = 1; // Central European Time
  16. //const int utcOffset = -5; // Eastern Standard Time (USA)
  17. //const int utcOffset = -4; // Eastern Daylight Time (USA)
  18. //const int utcOffset = -8; // Pacific Standard Time (USA)
  19. //const int utcOffset = -7; // Pacific Daylight Time (USA)
  20. // Packet buffer, must be big enough to packet and payload
  21. #define BUFFER_SIZE 550
  22. byte Ethernet::buffer[BUFFER_SIZE];
  23. const unsigned int remotePort = 123;
  24. void setup()
  25. {
  26. Serial.begin(9600);
  27. while (!Serial) // Needed for Leonardo only
  28. ;
  29. delay(250);
  30. Serial.println("TimeNTP_ENC28J60 Example");
  31. if (ether.begin(BUFFER_SIZE, mac) == 0) {
  32. // no point in carrying on, so do nothing forevermore:
  33. while (1) {
  34. Serial.println("Failed to access Ethernet controller");
  35. delay(10000);
  36. }
  37. }
  38. if (!ether.dhcpSetup()) {
  39. // no point in carrying on, so do nothing forevermore:
  40. while (1) {
  41. Serial.println("Failed to configure Ethernet using DHCP");
  42. delay(10000);
  43. }
  44. }
  45. ether.printIp("IP number assigned by DHCP is ", ether.myip);
  46. Serial.println("waiting for sync");
  47. //setSyncProvider(getNtpTime); // Use this for GMT time
  48. setSyncProvider(getDstCorrectedTime); // Use this for local, DST-corrected time
  49. }
  50. time_t prevDisplay = 0; // when the digital clock was displayed
  51. void loop()
  52. {
  53. if (timeStatus() != timeNotSet) {
  54. if (now() != prevDisplay) { //update the display only if time has changed
  55. prevDisplay = now();
  56. digitalClockDisplay();
  57. }
  58. }
  59. }
  60. void digitalClockDisplay(){
  61. // digital clock display of the time
  62. Serial.print(hour());
  63. printDigits(minute());
  64. printDigits(second());
  65. Serial.print(" ");
  66. Serial.print(day());
  67. Serial.print(" ");
  68. Serial.print(month());
  69. Serial.print(" ");
  70. Serial.print(year());
  71. Serial.println();
  72. }
  73. void printDigits(int digits){
  74. // utility for digital clock display: prints preceding colon and leading 0
  75. Serial.print(":");
  76. if(digits < 10)
  77. Serial.print('0');
  78. Serial.print(digits);
  79. }
  80. /*-------- NTP code ----------*/
  81. // SyncProvider that returns UTC time
  82. time_t getNtpTime()
  83. {
  84. // Send request
  85. Serial.println("Transmit NTP Request");
  86. if (!ether.dnsLookup(timeServer)) {
  87. Serial.println("DNS failed");
  88. return 0; // return 0 if unable to get the time
  89. } else {
  90. //ether.printIp("SRV: ", ether.hisip);
  91. ether.ntpRequest(ether.hisip, remotePort);
  92. // Wait for reply
  93. uint32_t beginWait = millis();
  94. while (millis() - beginWait < 1500) {
  95. word len = ether.packetReceive();
  96. ether.packetLoop(len);
  97. unsigned long secsSince1900 = 0L;
  98. if (len > 0 && ether.ntpProcessAnswer(&secsSince1900, remotePort)) {
  99. Serial.println("Receive NTP Response");
  100. return secsSince1900 - 2208988800UL;
  101. }
  102. }
  103. Serial.println("No NTP Response :-(");
  104. return 0;
  105. }
  106. }
  107. /* Alternative SyncProvider that automatically handles Daylight Saving Time (DST) periods,
  108. * at least in Europe, see below.
  109. */
  110. time_t getDstCorrectedTime (void) {
  111. time_t t = getNtpTime ();
  112. if (t > 0) {
  113. TimeElements tm;
  114. breakTime (t, tm);
  115. t += (utcOffset + dstOffset (tm.Day, tm.Month, tm.Year + 1970, tm.Hour)) * SECS_PER_HOUR;
  116. }
  117. return t;
  118. }
  119. /* This function returns the DST offset for the current UTC time.
  120. * This is valid for the EU, for other places see
  121. * http://www.webexhibits.org/daylightsaving/i.html
  122. *
  123. * Results have been checked for 2012-2030 (but should work since
  124. * 1996 to 2099) against the following references:
  125. * - http://www.uniquevisitor.it/magazine/ora-legale-italia.php
  126. * - http://www.calendario-365.it/ora-legale-orario-invernale.html
  127. */
  128. byte dstOffset (byte d, byte m, unsigned int y, byte h) {
  129. // Day in March that DST starts on, at 1 am
  130. byte dstOn = (31 - (5 * y / 4 + 4) % 7);
  131. // Day in October that DST ends on, at 2 am
  132. byte dstOff = (31 - (5 * y / 4 + 1) % 7);
  133. if ((m > 3 && m < 10) ||
  134. (m == 3 && (d > dstOn || (d == dstOn && h >= 1))) ||
  135. (m == 10 && (d < dstOff || (d == dstOff && h <= 1))))
  136. return 1;
  137. else
  138. return 0;
  139. }