/*NTP ESP-8266 Clock By Sebouh Please Use the Provided Librarerires For Compiling USE Arduino IDE 1.6.5 */ #include //https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266WiFi #include //https://github.com/esp8266/Arduino/tree/master/libraries/DNSServer #include //https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266WebServer #include //https://github.com/tzapu/WiFiManager #include //https://github.com/PaulStoffregen/Time #include //https://github.com/JChristensen/Timezone #include // https://github.com/wayoda/LedControl/releases MAX7219 7 segment driver /*For ESP-01 Don't Change GPIO Values // GPIO0= DIN pin, GPIO1 = CLK pin, GPIO 2 = LOAD pin LedControl lc = LedControl(0, 1, 2, 1) //Reset Button Connected On GPIO3 and Ground int inPin = 3; */ char* weekdays[] = { "So", "Mo", "Di", "Mi", "Do", "Fr", "Sa" }; const char compile_date[] = __DATE__ " " __TIME__ " " __FILE__; // HOSTNAME for OTA update #define HOSTNAME "ESP8266-OTA-" //For ESP-07 Tested GPIO Values // EasyESP or NodeMCU Pin D8 to DIN, D7 to Clk, D6 to LOAD, no.of devices is 1 LedControl lc = LedControl(D8, D7, D6, 2); // the GPIO number For The "Reset" Push Button Switch Pin For ESp-07 Tested int inPin = 5; //Edit These Lines According To Your Timezone and Daylight Saving Time //TimeZone Settings Details https://github.com/JChristensen/Timezone TimeChangeRule CEST = {"CEST", Last, Sun, Mar, 2, 120}; //Central European Time (Frankfurt, Paris) TimeChangeRule CET = {"CET ", Last, Sun, Oct, 3, 60}; //Central European Time (Frankfurt, Paris) Timezone CE(CEST, CET); //Pointer To The Time Change Rule, Use to Get The TZ Abbrev TimeChangeRule *tcr; time_t utc, local; // time_t utc ; //NTP Server http://tf.nist.gov/tf-cgi/servers.cgi static const char ntpServerName[] = "de.pool.ntp.org"; WiFiUDP Udp; // Local Port to Listen For UDP Packets uint16_t localPort; int devices; bool Flag; // ------------------------------------------------------------------------------------------ // Setup Details void setup() { Serial.begin(115200); Serial.println(); Serial.println(compile_date); //we have already set the number of devices when we created the LedControl devices = lc.getDeviceCount(); //we have to init all devices in a loop for (int address = 0; address < devices; address++) { /*The MAX72XX is in power-saving mode on startup*/ lc.shutdown(address, false); /* Set the brightness to a medium values */ lc.setIntensity(address, 5); /* and clear the display */ lc.clearDisplay(address); } //Display lc.setRow(0, 6, 0x5b); lc.setRow(0, 5, 0x0f); lc.setRow(0, 4, 0x77); lc.setRow(0, 3, 0x05); lc.setRow(0, 2, 0x0f); delay(500); // Switch Type pinMode(inPin, INPUT_PULLUP); //WiFiManager //Local intialization. WiFiManager wifiManager; //AP Configuration wifiManager.setAPCallback(configModeCallback); //Exit After Config Instead of connecting wifiManager.setBreakAfterConfig(true); //Reset Settings - If Button Pressed if (digitalRead(inPin) == LOW) { //Display lc.clearDisplay(0); lc.setRow(0, 6, 0x05); lc.setRow(0, 5, 0x4f); lc.setRow(0, 4, 0x5b); lc.setRow(0, 3, 0x6f); lc.setRow(0, 2, 0x0f); delay(5000); wifiManager.resetSettings(); //ESP.reset(); ESP.restart(); } /* Tries to connect to last known settings if it does not connect it starts an access point with the specified name here "AutoConnectAP" without password (uncomment below line and comment next line if password required) and goes into a blocking loop awaiting configuration */ //If You Require Password For Your NTP Clock // if (!wifiManager.autoConnect("NTP Clock", "password")) //If You Dont Require Password For Your NTP Clock if (!wifiManager.autoConnect("NTP-Clock")) { delay(3000); ESP.reset(); delay(5000); } //Display Once Connected to AP lc.setRow(0, 7, 0x4e); lc.setRow(0, 6, 0x1d); lc.setRow(0, 5, 0x15); lc.setRow(0, 4, 0x15); lc.setChar(0, 3, 'E', false); lc.setRow(0, 2, 0x0d); lc.setRow(0, 1, 0x0f); Serial.println("Connect"); delay(3000); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } char result[255]; sprintf(result, "WebServer ready at %1d.%1d.%1d.%1d", WiFi.localIP()[0], WiFi.localIP()[1], WiFi.localIP()[2], WiFi.localIP()[3]); Serial.println(); Serial.println(result); // Seed Random With vVlues Unique To This Device uint8_t macAddr[6]; WiFi.macAddress(macAddr); uint32_t seed1 = (macAddr[5] << 24) | (macAddr[4] << 16) | (macAddr[3] << 8) | macAddr[2]; // randomSeed(WiFi.localIP() + seed1 + micros()); randomSeed(seed1 + micros()); localPort = 8888; localPort = random(1024, 65535); Udp.begin(localPort); setSyncProvider(getNtpTime); //Set Sync Intervals setSyncInterval(5 * 60); } void loop() { // when the digital clock was displayed static time_t prevDisplay = 0; timeStatus_t ts = timeStatus(); utc = now(); switch (ts) { case timeNeedsSync: Serial.println("timeNeedsSync"); case timeSet: //update the display only if time has changed if (now() != prevDisplay) { prevDisplay = now(); digitalClockDisplay(); tmElements_t tm; breakTime(now(), tm); //If Time Needs Sync Display a "-" On Last Digit if (ts == timeNeedsSync) { // lc.setChar(0, 1, '-', false); lc.setChar(0, 2, '_', false); } //else { //lc.setDigit(0, 2, (second() % 10), false); // } } break; case timeNotSet: //Display If Time Not Displayed lc.clearDisplay(0); lc.setRow(0, 7, 0x15); lc.setRow(0, 6, 0x1d); lc.setRow(0, 4, 0x5b); lc.setRow(0, 3, 0x3b); lc.setRow(0, 2, 0x15); lc.setRow(0, 1, 0x0d); Serial.println("No Sync"); now(); delay(3000); ESP.restart(); } } //##################################################### unsigned int HexToBCD(unsigned int number) { unsigned char i = 0; unsigned int k = 0; while (number) { k = (k) | ((number % 10) << i * 4); number = number / 10; i++; } return (k); } void digitalClockDisplay() { tmElements_t tm; char *dayOfWeek; breakTime(now(), tm); lc.clearDisplay(0); // Start with left digit int H = int(hour(CE.toLocal(utc, &tcr)) / 10); if (H == 0) { lc.setChar(0, 7, ' ', false); } else { lc.setDigit(0, 7, H, false); } lc.setDigit(0, 6, (hour(CE.toLocal(utc, &tcr)) % 10), false); lc.setChar(0, 5, '-', false); lc.setDigit(0, 4, (minute() / 10), false); lc.setDigit(0, 3, (minute() % 10), false); lc.setChar(0, 2, '-', false); lc.setDigit(0, 1, int(second() / 10), false); lc.setDigit(0, 0, (second() % 10), false); int D = int(day(CE.toLocal(utc, &tcr)) / 10); if (D == 0) { lc.setChar(1, 7, ' ', false); } else { lc.setDigit(1, 7, D, false); } lc.setDigit(1, 6, (day(CE.toLocal(utc, &tcr)) % 10), true); int M = int(month(CE.toLocal(utc, &tcr)) / 10); if (M == 0) { lc.setChar(1, 5, ' ', false); } else { lc.setDigit(1, 5, M, false); } lc.setDigit(1, 4, (month(CE.toLocal(utc, &tcr)) % 10), true); unsigned int count_one; count_one = HexToBCD(year(CE.toLocal(utc, &tcr))); lc.setDigit(1, 3, ((count_one >> 12) & 0x0F), false); lc.setDigit(1, 2, ((count_one >> 8) & 0x0F), false); lc.setDigit(1, 1, ((count_one >> 4) & 0x0F), false); lc.setDigit(1, 0, (count_one & 0x0F), false); utc = now(); local = CE.toLocal(utc, &tcr); printTime(local, tcr -> abbrev); } // ---------------------------------------------- // Function to print time with time zone // ---------------------------------------------- void printTime(time_t t, char *tz) { char cb [128]; 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 ) ; Serial.println(cb); } /*-------- NTP code ----------*/ const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets time_t getNtpTime() { IPAddress timeServerIP; // time.nist.gov NTP server address while (Udp.parsePacket() > 0) ; // discard any previously received packets Serial.print(F("Transmit NTP Request ")); //get a random server from the pool WiFi.hostByName(ntpServerName, timeServerIP); Serial.println(timeServerIP); sendNTPpacket(timeServerIP); uint32_t beginWait = millis(); while ((millis() - beginWait) < 1500) { int size = Udp.parsePacket(); if (size >= NTP_PACKET_SIZE) { Udp.read(packetBuffer, NTP_PACKET_SIZE); // read packet into the buffer unsigned long secsSince1900; // convert four bytes starting at location 40 to a long integer secsSince1900 = (unsigned long)packetBuffer[40] << 24; secsSince1900 |= (unsigned long)packetBuffer[41] << 16; secsSince1900 |= (unsigned long)packetBuffer[42] << 8; secsSince1900 |= (unsigned long)packetBuffer[43]; return secsSince1900 - 2208988800UL; } } return 0; // return 0 if unable to get the time } // send an NTP request to the time server at the given address void sendNTPpacket(IPAddress &address) { // set all bytes in the buffer to 0 memset(packetBuffer, 0, NTP_PACKET_SIZE); // Initialize values needed to form NTP request // (see URL above for details on the packets) packetBuffer[0] = 0b11100011; // LI, Version, Mode packetBuffer[1] = 0; // Stratum, or type of clock packetBuffer[2] = 6; // Polling Interval packetBuffer[3] = 0xEC; // Peer Clock Precision // 8 bytes of zero for Root Delay & Root Dispersion packetBuffer[12] = 49; packetBuffer[13] = 0x4E; packetBuffer[14] = 49; packetBuffer[15] = 52; // all NTP fields have been given values, now // you can send a packet requesting a timestamp: Udp.beginPacket(address, 123); //NTP requests are to port 123 Udp.write(packetBuffer, NTP_PACKET_SIZE); Udp.endPacket(); } //To Display if not connected to AP void configModeCallback (WiFiManager *myWiFiManager) { lc.clearDisplay(0); lc.setRow(0, 7, 0x5b); lc.setChar(0, 6, 'E', false); lc.setRow(0, 5, 0x0f); lc.setRow(0, 4, 0x03e); lc.setChar(0, 3, 'P', false); delay(2000); }