Advertisement
NittyGritty

NTP_WiFi_Clock.ino

Jan 16th, 2022
1,015
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.70 KB | None | 0 0
  1. /*NTP ESP-8266 Clock By Sebouh
  2.   Please Use the Provided Librarerires
  3.   For Compiling USE Arduino IDE 1.6.5
  4. */
  5. #include <ESP8266WiFi.h>          //https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266WiFi
  6. #include <DNSServer.h>            //https://github.com/esp8266/Arduino/tree/master/libraries/DNSServer
  7. #include <ESP8266WebServer.h>     //https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266WebServer
  8. #include <WiFiManager.h>          //https://github.com/tzapu/WiFiManager
  9. #include <TimeLib.h>              //https://github.com/PaulStoffregen/Time
  10. #include <Timezone.h>             //https://github.com/JChristensen/Timezone
  11. #include <LedControl.h>           // https://github.com/wayoda/LedControl/releases  MAX7219 7 segment driver
  12.  
  13.  
  14. /*For ESP-01 Don't Change GPIO Values
  15.   // GPIO0= DIN pin, GPIO1 = CLK pin, GPIO 2 = LOAD pin
  16.   LedControl lc = LedControl(0, 1, 2, 1)
  17.   //Reset Button Connected On GPIO3 and Ground
  18.   int inPin = 3;
  19. */
  20.  
  21. char* weekdays[] = { "So", "Mo", "Di", "Mi", "Do", "Fr", "Sa" };
  22. const char compile_date[] = __DATE__ " " __TIME__ " " __FILE__;
  23. // HOSTNAME for OTA update
  24. #define HOSTNAME "ESP8266-OTA-"
  25.  
  26. //For ESP-07 Tested GPIO Values
  27. // EasyESP or NodeMCU Pin D8 to DIN, D7 to Clk, D6 to LOAD, no.of devices is 1
  28. LedControl lc = LedControl(D8, D7, D6, 2);
  29.  
  30. // the GPIO number For The "Reset" Push Button Switch Pin For ESp-07 Tested
  31. int inPin = 5;
  32. //Edit These Lines According To Your Timezone and Daylight Saving Time
  33. //TimeZone Settings Details https://github.com/JChristensen/Timezone
  34. TimeChangeRule CEST = {"CEST", Last, Sun, Mar, 2, 120};     //Central European Time (Frankfurt, Paris)
  35. TimeChangeRule CET = {"CET ", Last, Sun, Oct, 3, 60};       //Central European Time (Frankfurt, Paris)
  36. Timezone CE(CEST, CET);
  37. //Pointer To The Time Change Rule, Use to Get The TZ Abbrev
  38. TimeChangeRule *tcr;
  39. time_t utc, local;
  40. // time_t utc ;
  41.  
  42.  
  43. //NTP Server http://tf.nist.gov/tf-cgi/servers.cgi
  44. static const char ntpServerName[] = "de.pool.ntp.org";
  45. WiFiUDP Udp;
  46. // Local Port to Listen For UDP Packets
  47. uint16_t localPort;
  48. int devices;
  49. bool Flag;
  50. // ------------------------------------------------------------------------------------------
  51. // Setup Details
  52. void setup() {
  53.  
  54.   Serial.begin(115200);
  55.   Serial.println();
  56.   Serial.println(compile_date);
  57.  
  58.   //we have already set the number of devices when we created the LedControl
  59.   devices = lc.getDeviceCount();
  60.  
  61.   //we have to init all devices in a loop
  62.   for (int address = 0; address < devices; address++) {
  63.     /*The MAX72XX is in power-saving mode on startup*/
  64.     lc.shutdown(address, false);
  65.     /* Set the brightness to a medium values */
  66.     lc.setIntensity(address, 5);
  67.     /* and clear the display */
  68.     lc.clearDisplay(address);
  69.   }
  70.  
  71.   //Display <StArt>
  72.   lc.setRow(0, 6, 0x5b);
  73.   lc.setRow(0, 5, 0x0f);
  74.   lc.setRow(0, 4, 0x77);
  75.   lc.setRow(0, 3, 0x05);
  76.   lc.setRow(0, 2, 0x0f);
  77.   delay(500);
  78.  
  79.   // Switch Type
  80.   pinMode(inPin, INPUT_PULLUP);
  81.  
  82.   //WiFiManager
  83.   //Local intialization.
  84.   WiFiManager wifiManager;
  85.   //AP Configuration
  86.   wifiManager.setAPCallback(configModeCallback);
  87.   //Exit After Config Instead of connecting
  88.   wifiManager.setBreakAfterConfig(true);
  89.  
  90.   //Reset Settings - If Button Pressed
  91.   if (digitalRead(inPin) == LOW) {
  92.     //Display <Reset>
  93.     lc.clearDisplay(0);
  94.     lc.setRow(0, 6, 0x05);
  95.     lc.setRow(0, 5, 0x4f);
  96.     lc.setRow(0, 4, 0x5b);
  97.     lc.setRow(0, 3, 0x6f);
  98.     lc.setRow(0, 2, 0x0f);
  99.     delay(5000);
  100.     wifiManager.resetSettings();
  101.     //ESP.reset();
  102.     ESP.restart();
  103.   }
  104.   /*
  105.     Tries to connect to last known settings
  106.     if it does not connect it starts an access point with the specified name
  107.     here  "AutoConnectAP" without password (uncomment below line and comment
  108.     next line if password required)
  109.     and goes into a blocking loop awaiting configuration
  110.   */
  111.   //If You Require Password For Your NTP Clock
  112.   // if (!wifiManager.autoConnect("NTP Clock", "password"))
  113.   //If You Dont Require Password For Your NTP Clock
  114.   if (!wifiManager.autoConnect("NTP-Clock")) {
  115.     delay(3000);
  116.     ESP.reset();
  117.     delay(5000);
  118.   }
  119.  
  120.   //Display <Connect> Once Connected to AP
  121.   lc.setRow(0, 7, 0x4e);
  122.   lc.setRow(0, 6, 0x1d);
  123.   lc.setRow(0, 5, 0x15);
  124.   lc.setRow(0, 4, 0x15);
  125.   lc.setChar(0, 3, 'E', false);
  126.   lc.setRow(0, 2, 0x0d);
  127.   lc.setRow(0, 1, 0x0f);
  128.   Serial.println("Connect");
  129.   delay(3000);
  130.  
  131.   while (WiFi.status() != WL_CONNECTED) {
  132.     delay(500);
  133.     Serial.print(".");
  134.   }
  135.  
  136.   char result[255];
  137.   sprintf(result, "WebServer ready at %1d.%1d.%1d.%1d", WiFi.localIP()[0], WiFi.localIP()[1], WiFi.localIP()[2], WiFi.localIP()[3]);
  138.   Serial.println();
  139.   Serial.println(result);
  140.  
  141.   // Seed Random With vVlues Unique To This Device
  142.   uint8_t macAddr[6];
  143.   WiFi.macAddress(macAddr);
  144.   uint32_t seed1 =
  145.     (macAddr[5] << 24) | (macAddr[4] << 16) |
  146.     (macAddr[3] << 8)  | macAddr[2];
  147.   // randomSeed(WiFi.localIP() + seed1 + micros());
  148.   randomSeed(seed1 + micros());
  149.   localPort = 8888;
  150.   localPort = random(1024, 65535);
  151.   Udp.begin(localPort);
  152.   setSyncProvider(getNtpTime);
  153.  
  154.   //Set Sync Intervals
  155.   setSyncInterval(5 * 60);
  156.  
  157. }
  158. void loop() {
  159.   // when the digital clock was displayed
  160.   static time_t prevDisplay = 0;
  161.   timeStatus_t ts = timeStatus();
  162.   utc = now();
  163.   switch (ts) {
  164.     case timeNeedsSync:
  165.       Serial.println("timeNeedsSync");
  166.     case timeSet:
  167.       //update the display only if time has changed
  168.       if (now() != prevDisplay) {
  169.         prevDisplay = now();
  170.         digitalClockDisplay();
  171.         tmElements_t tm;
  172.         breakTime(now(), tm);
  173.         //If Time Needs Sync Display a "-" On Last Digit
  174.         if (ts == timeNeedsSync) {
  175.           // lc.setChar(0, 1, '-', false);
  176.           lc.setChar(0, 2, '_', false);
  177.  
  178.         }
  179.         //else {
  180.         //lc.setDigit(0, 2, (second() % 10), false);
  181.         //  }
  182.       }
  183.       break;
  184.     case timeNotSet:
  185.       //Display <No Sync> If Time Not Displayed
  186.       lc.clearDisplay(0);
  187.       lc.setRow(0, 7, 0x15);
  188.       lc.setRow(0, 6, 0x1d);
  189.       lc.setRow(0, 4, 0x5b);
  190.       lc.setRow(0, 3, 0x3b);
  191.       lc.setRow(0, 2, 0x15);
  192.       lc.setRow(0, 1, 0x0d);
  193.       Serial.println("No Sync");
  194.       now();
  195.       delay(3000);
  196.       ESP.restart();
  197.   }
  198. }
  199. //#####################################################
  200.  
  201. unsigned int HexToBCD(unsigned int number)
  202. {
  203.   unsigned char i = 0;
  204.   unsigned int k = 0;
  205.  
  206.   while (number)
  207.   {
  208.     k = (k) | ((number % 10) << i * 4);
  209.     number = number / 10;
  210.     i++;
  211.   }
  212.  
  213.   return (k);
  214. }
  215.  
  216. void digitalClockDisplay() {
  217.  
  218.   tmElements_t tm;
  219.   char *dayOfWeek;
  220.   breakTime(now(), tm);
  221.   lc.clearDisplay(0);
  222.   // Start with left digit
  223.   int H = int(hour(CE.toLocal(utc, &tcr)) / 10);
  224.   if (H == 0) {
  225.     lc.setChar(0, 7, ' ', false);
  226.   } else {
  227.     lc.setDigit(0, 7, H, false);
  228.   }
  229.  
  230.   lc.setDigit(0, 6, (hour(CE.toLocal(utc, &tcr)) % 10), false);
  231.   lc.setChar(0, 5, '-', false);
  232.   lc.setDigit(0, 4, (minute() / 10), false);
  233.   lc.setDigit(0, 3, (minute() % 10), false);
  234.   lc.setChar(0, 2, '-', false);
  235.   lc.setDigit(0, 1, int(second() / 10), false);
  236.   lc.setDigit(0, 0, (second() % 10), false);
  237.  
  238.   int D = int(day(CE.toLocal(utc, &tcr)) / 10);
  239.   if (D == 0) {
  240.     lc.setChar(1, 7, ' ', false);
  241.   } else {
  242.     lc.setDigit(1, 7, D, false);
  243.   }
  244.   lc.setDigit(1, 6, (day(CE.toLocal(utc, &tcr)) % 10), true);
  245.  
  246.   int M = int(month(CE.toLocal(utc, &tcr)) / 10);
  247.   if (M == 0) {
  248.     lc.setChar(1, 5, ' ', false);
  249.   } else {
  250.     lc.setDigit(1, 5, M, false);
  251.   }
  252.   lc.setDigit(1, 4, (month(CE.toLocal(utc, &tcr)) % 10), true);
  253.  
  254.   unsigned int count_one;
  255.   count_one = HexToBCD(year(CE.toLocal(utc, &tcr)));
  256.  
  257.   lc.setDigit(1, 3, ((count_one >> 12) & 0x0F), false);
  258.   lc.setDigit(1, 2, ((count_one >> 8) & 0x0F), false);
  259.   lc.setDigit(1, 1, ((count_one >> 4) & 0x0F), false);
  260.   lc.setDigit(1, 0, (count_one & 0x0F), false);
  261.  
  262.   utc = now();
  263.   local = CE.toLocal(utc, &tcr);
  264.   printTime(local, tcr -> abbrev);
  265.  
  266. }
  267.  
  268. // ----------------------------------------------
  269. // Function to print time with time zone
  270. // ----------------------------------------------
  271. void printTime(time_t t, char *tz)
  272. {
  273.   char cb [128];
  274.  
  275.   sprintf(cb, "%s, %02d.%02d.%04d %02d:%02d:%02d %s", (weekdays[weekday(t) - 1]), day(t), month(t), year(t), hour(t), minute(t), second(t), tz ) ;
  276.   Serial.println(cb);
  277. }
  278.  
  279.  
  280. /*-------- NTP code ----------*/
  281.  
  282. const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message
  283. byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets
  284.  
  285. time_t getNtpTime()
  286. {
  287.   IPAddress timeServerIP; // time.nist.gov NTP server address
  288.  
  289.   while (Udp.parsePacket() > 0) ; // discard any previously received packets
  290.   Serial.print(F("Transmit NTP Request "));
  291.   //get a random server from the pool
  292.   WiFi.hostByName(ntpServerName, timeServerIP);
  293.   Serial.println(timeServerIP);
  294.  
  295.   sendNTPpacket(timeServerIP);
  296.   uint32_t beginWait = millis();
  297.   while ((millis() - beginWait) < 1500) {
  298.     int size = Udp.parsePacket();
  299.     if (size >= NTP_PACKET_SIZE) {
  300.       Udp.read(packetBuffer, NTP_PACKET_SIZE);  // read packet into the buffer
  301.       unsigned long secsSince1900;
  302.       // convert four bytes starting at location 40 to a long integer
  303.       secsSince1900 =  (unsigned long)packetBuffer[40] << 24;
  304.       secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
  305.       secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
  306.       secsSince1900 |= (unsigned long)packetBuffer[43];
  307.       return secsSince1900 - 2208988800UL;
  308.     }
  309.   }
  310.   return 0; // return 0 if unable to get the time
  311. }
  312. // send an NTP request to the time server at the given address
  313. void sendNTPpacket(IPAddress &address)
  314. {
  315.  
  316.   // set all bytes in the buffer to 0
  317.   memset(packetBuffer, 0, NTP_PACKET_SIZE);
  318.   // Initialize values needed to form NTP request
  319.   // (see URL above for details on the packets)
  320.   packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  321.   packetBuffer[1] = 0;     // Stratum, or type of clock
  322.   packetBuffer[2] = 6;     // Polling Interval
  323.   packetBuffer[3] = 0xEC;  // Peer Clock Precision
  324.   // 8 bytes of zero for Root Delay & Root Dispersion
  325.   packetBuffer[12]  = 49;
  326.   packetBuffer[13]  = 0x4E;
  327.   packetBuffer[14]  = 49;
  328.   packetBuffer[15]  = 52;
  329.   // all NTP fields have been given values, now
  330.   // you can send a packet requesting a timestamp:
  331.   Udp.beginPacket(address, 123); //NTP requests are to port 123
  332.   Udp.write(packetBuffer, NTP_PACKET_SIZE);
  333.   Udp.endPacket();
  334. }
  335. //To Display <Setup> if not connected to AP
  336. void configModeCallback (WiFiManager *myWiFiManager) {
  337.   lc.clearDisplay(0);
  338.   lc.setRow(0, 7, 0x5b);
  339.   lc.setChar(0, 6, 'E', false);
  340.   lc.setRow(0, 5, 0x0f);
  341.   lc.setRow(0, 4, 0x03e);
  342.   lc.setChar(0, 3, 'P', false);
  343.   delay(2000);
  344. }
  345.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement