Advertisement
RehabCZ

NTP to DCF77 converter for ESP8266.

Apr 10th, 2025 (edited)
335
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Arduino 7.60 KB | Source Code | 0 0
  1. /*
  2.   2017-09-10 Hiroki Mori
  3. */
  4.  
  5. #include <ESP8266WiFi.h>
  6. #include <NTPClient.h>
  7. #include <WiFiUdp.h>
  8. #include <time.h>
  9.  
  10. // ========== CONFIG STARTS HERE ==========//
  11.  
  12. /*
  13.  Address of NTP server from which we would grab time data
  14. */
  15. #define NTPSERVER ""
  16.  
  17. /*
  18. +----------+------------------------------------------------------+---------+
  19. | TIME VAL |                     DESCRIPTION                      | GMT VAL |
  20. +----------+------------------------------------------------------+---------+
  21. |    43200 | International Date Line West                         | -12:00  |
  22. |   -39600 | Midway Island, Samoa                                 | -11:00  |
  23. |   -36000 | Hawaii                                               | -10:00  |
  24. |   -34200 | French Polynesia, Marquesas Islands                  | -09:30  |
  25. |   -32400 | Alaska                                               | -09:00  |
  26. |   -28800 | Pacific Time (US & Canada)                           | -08:00  |
  27. |   -25200 | Mountain Time (US & Canada)                          | -07:00  |
  28. |   -21600 | Central Time (US & Canada), Guadalajara, Mexico city | -06:00  |
  29. |   -18000 | Eastern time (US & Canada)                           | -05:00  |
  30. |   -16200 | Venezuela                                            | -04:30  |
  31. |   -14400 | Atlantic time (Canada), Manaus, Santiago             | -04:00  |
  32. |   -12600 | Newfoundland                                         | -03:30  |
  33. |   -10800 | Greenland, Brasilia, Montevideo                      | -03:00  |
  34. |    -7200 | Mid-Atlantic                                         | -02:00  |
  35. |    -3600 | Azores                                               | -01:00  |
  36. |        0 | GMT: Dublin, Edinburgh, Lisbon, London               | 00:00   |
  37. |     3600 | Amsterdam, Berlin, Rome, Vienna, Prague, Brussels    | +01:00  |
  38. |     7200 | Athens, Istanbul, Beirut, Cairo, Jerusalem           | +02:00  |
  39. |    10800 | St. Petersburg, Minsk, Baghdad, Moscow               | +03:00  |
  40. |    12600 | Iran                                                 | +03:30  |
  41. |    14400 | Volgograd, Baku, Yerevan                             | +04:00  |
  42. |    16200 | Afghanistan                                          | +04:30  |
  43. |    18000 | Yekaterinburg, Tashkent                              | +05:00  |
  44. |    19800 | Chennai, Kolkata, Mumbai, New Delhi                  | +05:30  |
  45. |    20700 | Nepal                                                | +05:45  |
  46. |    21600 | Omsk, Almaty                                         | +06:00  |
  47. |    23400 | Myanmar, Cocos Islands                               | +06:30  |
  48. |    25200 |                                                      | +07:00  |
  49. |    28800 | Krasnoyarsk, Ulaan Bataar, Perth                     | +08:00  |
  50. |    32400 | Irkutsk                                              | +09:00  |
  51. |    34200 | Australian Central Standard Time                     | +09:30  |
  52. |    36000 | Yakutsk, Canberra, Melbourne, Sydney, Hobart         | +10:00  |
  53. |    37800 | Lord Howe Standard Time                              | +10:30  |
  54. |    39600 | Vladivostok, Solomon Is., New Caledonia              | +11:00  |
  55. |    41400 | Norfolk Islan                                        | +11:30  |
  56. |    43200 | Magadan, Auckland, Wellington                        | +12:00  |
  57. |    45900 | New Zealand, Chatham Island                          | +12:45  |
  58. |    46800 | Nuku'alofa                                           | +13:00  |
  59. |    50400 | Kiribati, Line Islands                               | +14:00  |
  60. +----------+------------------------------------------------------+---------+
  61. */
  62. #define TIMEOFFSET 32400
  63.  
  64. /*
  65.  Output pin to produce DCF77 signal to
  66. */
  67. #define DCF77OUT 13
  68.  
  69. /*
  70.  WIFI Network credentials
  71. */
  72. const char ssid[] = "";
  73. const char passwd[] = "";
  74.  
  75. // ========== CONFIG ENDS HERE ========== //
  76.  
  77. WiFiUDP ntpUDP;
  78.  
  79. NTPClient timeClient(ntpUDP, NTPSERVER, TIMEOFFSET, 0);
  80.  
  81. int count = 0;
  82. int unixtime;
  83. int starttime;
  84.  
  85. long lobit = 0;   // 0 - 28
  86. long hibit = 0;   // 29 - 59
  87.  
  88. bool isConnected() {
  89.   return WiFi.status() == WL_CONNECTED;
  90. }
  91.  
  92. bool waitConnect() {
  93.   int i = 0;
  94.   Serial.println("now waiting");
  95.   while(!isConnected()) {
  96.     Serial.print(".");
  97.     delay(1000);
  98.     ++i;
  99.     if(i > 60)
  100.       break;
  101.   }
  102.   if(WiFi.status() != WL_CONNECTED)
  103.     return false;
  104.  
  105.   // Print network details
  106.   Serial.println("connected!");
  107.   Serial.print("IPAddress: ");
  108.   Serial.println(WiFi.localIP());
  109.  
  110.   return true;
  111. }
  112.  
  113. void timer0_ISR (void) {
  114.   int curbit;
  115.   int sec;
  116.   sec = count / 10;
  117.   if(lobit != 0) {
  118.     if(count < 290) {
  119.       curbit = (lobit >> sec) & 1;
  120.     } else {
  121.       curbit = (hibit >> (sec - 29)) & 1;
  122.     }
  123.  
  124.     if(sec != 59) {
  125.       if (count % 10 == 0) {
  126.         digitalWrite(DCF77OUT, HIGH);
  127.       } else if(count % 10 == 1 && curbit == 0) {
  128.         digitalWrite(DCF77OUT, LOW);
  129.       } else if(count % 10 == 2 && curbit == 1) {
  130.         digitalWrite(DCF77OUT, LOW);
  131.       }
  132.     }
  133.   }
  134.   if(count == 590) {
  135.     mkdcf77();
  136.   }
  137.   if(count % 10 == 0)
  138.     ++unixtime;
  139.   ++count;
  140.   if(count == 600)
  141.     count = 0;
  142.   timer0_write(ESP.getCycleCount() + 8000000L); // 8MHz == 100ms
  143. }
  144.  
  145. void mkdcf77()
  146. {
  147. int minutes, hours, week, day, month, year;
  148. int parity;
  149. int i;
  150. struct tm *date;
  151. int nexttime = unixtime + 2 + 60;
  152. time_t now = nexttime;
  153.  
  154.   minutes = (nexttime % 3600) / 60;
  155.   hours = (nexttime % 86400L) / 3600;
  156.   week = ((nexttime / 86400L) + 3) % 7 + 1;
  157.  
  158.   date = localtime(&now);
  159.   day = date->tm_mday;
  160.   month = date->tm_mon + 1;
  161.   year = date->tm_year-100;
  162.  
  163.   // Print encoded time data
  164.   Serial.print(year);
  165.   Serial.print("-");
  166.   Serial.print(month);
  167.   Serial.print("-");
  168.   Serial.print(day);
  169.   Serial.print("/");
  170.   Serial.print(week);
  171.   Serial.print(" ");
  172.   Serial.print(hours);
  173.   Serial.print(":");
  174.   Serial.println(minutes);
  175.  
  176.   lobit = 0;
  177.   hibit = 0;
  178.  
  179.   lobit |= 1 << 18;   // CET
  180.   lobit |= 1 << 20;   // Start Bit
  181.   lobit |= (minutes % 10) << 21;   // Minutes
  182.   lobit |= (minutes / 10) << 25;
  183.  
  184.   hibit |= (hours % 10);   // Hours
  185.   hibit |= (hours / 10) << 4;
  186.   hibit |= (day % 10) << 7;   // Day of month
  187.   hibit |= (day / 10) << 11;
  188.   hibit |= week << 13;   // Day of week
  189.   hibit |= (month % 10) << 16;  // Month number
  190.   hibit |= (month / 10) << 20;
  191.   hibit |= (year % 10) << 21;   // Year within century
  192.   hibit |= (year / 10) << 25;
  193.  
  194.   parity = 0;
  195.   for(i = 21; i <= 27; ++i) {
  196.     parity += (lobit >> i) & 1;
  197.   }
  198.   if(parity & 1)
  199.     lobit |= 1 << 28;
  200.  
  201.   parity = 0;
  202.   for(i = 0; i <= 5; ++i) {
  203.     parity += (hibit >> i) & 1;
  204.   }
  205.   if(parity & 1)
  206.     hibit |= 1 << 6;
  207.  
  208.   parity = 0;
  209.   for(i = 7; i <= 28; ++i) {
  210.     parity += (hibit >> i) & 1;
  211.   }
  212.   if(parity & 1)
  213.     hibit |= 1 << 29;
  214. }
  215.  
  216. void setup() {
  217.   Serial.begin(115200);
  218.  
  219.   WiFi.mode(WIFI_STA);
  220.   WiFi.begin(ssid, passwd);
  221.   if(waitConnect() == false) {
  222.     Serial.println("Can't connect");
  223.     ESP.deepSleep(0);
  224.     return;
  225.   }
  226.  
  227.   timeClient.begin();
  228.   timeClient.update();
  229.  
  230.   unixtime = timeClient.getEpochTime();
  231.   starttime = unixtime;
  232.   count = (unixtime % 60) * 10;
  233.   Serial.println(unixtime);
  234.   if(unixtime < 946652400) { // before 2000/01/01 00:00:00
  235.     Serial.println("Can't get time");
  236.     ESP.deepSleep(0);
  237.     return;
  238.   }
  239.  
  240.   WiFi.disconnect();
  241.   delay(1);
  242.   WiFi.mode(WIFI_OFF);
  243.   WiFi.forceSleepBegin();
  244.   delay(1);
  245.  
  246.   pinMode(DCF77OUT, OUTPUT);
  247.   noInterrupts();
  248.   timer0_isr_init();
  249.   timer0_attachInterrupt(timer0_ISR);
  250.   timer0_write(ESP.getCycleCount() + 8000000L); // 8MHz == 100ms
  251.   interrupts();
  252. }
  253.  
  254. void loop()
  255. {
  256.   if(unixtime - starttime > 60 * 5) {
  257.     ESP.deepSleep(0);
  258.   }
  259. }
Tags: NTP DCF
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement