Features
- WiFi Connectivity: Uses the ESP8266 to connect to your WiFi network.
- NTP Time Synchronization: Synchronizes time with an NTP server to ensure accurate timekeeping.
- 7-Segment Display: Displays hours and minutes on a 7-segment display controlled via shift registers.
- Adjustable Brightness: Automatically adjusts the display brightness based on ambient light using an LDR (Light Dependent Resistor).
- Auto-Reboot: Automatically reboots the ESP8266 every 24 hours to ensure stability.
- WiFiManager: Simplifies WiFi configuration with a web-based setup page.
Components Used
- ESP8266 (ESP12F/ESP12E)
- 74HC595 Shift Registers
- 7-Segment Display / Make it yourself using leds
- NPN transistors (4 pieces) for each digit
- LDR (Light Dependent Resistor)
- LED Indicator
- Push Button for WiFi Reset
Schematic

How It Works
Initialization: The ESP8266 connects to the configured WiFi network using the WiFiManager library. If the connection fails, it enters WiFi setup mode. NTP Synchronization: The ESP8266 fetches the current time from an NTP server (in.pool.ntp.org) and calculates the local time with the specified timezone correction. Display Update: The time is displayed on a 7-segment display using shift registers. The display is updated every second. Brightness Adjustment: The brightness of the display is adjusted every 10 milliseconds based on the ambient light detected by the LDR. LED Indicator: An LED blinks every 500 milliseconds to indicate the clock is running. Automatic Reboot: The ESP8266 reboots every 24 hours to ensure the system remains stable and responsive.
Code Overview
Libraries Used
- ESP8266WiFi.h: Manages WiFi connections.
- WiFiManager.h: Simplifies WiFi setup and connection.
- WiFiUdp.h: Handles UDP communication for NTP.
- Ticker.h: Provides periodic interrupt functionality.
Key Functions
- setup(): Initializes the ESP8266, connects to WiFi, sets up timers, and fetches the initial time.
- loop(): Continuously updates the display and checks for button presses to reset WiFi settings.
- getDateTime(): Fetches the current time from the NTP server and sets the epoch time.
- displayDigit(): Sends data to the shift registers to update the 7-segment display.
- adjustBrightness(): Adjusts the display brightness based on the LDR reading.
- updateDisplay(): Updates the display with the current time.
- tick(): Increments the time by one second and updates the hour, minute, and second variables.
- reboot(): Reboots the ESP8266.
Code
#include < esp8266wifi.h >
#include < wificlient.h >
#include < wifiudp.h >
#include < ntpclient.h >
Ticker ticker;
Ticker Timer500ms;
Ticker BrightnessTicker;
Ticker tickerRefresh;
WiFiManager wifiMn;
unsigned int localPort = 123; // local port to listen for UDP packets
IPAddress timeServerIP; // time.nist.gov NTP server address
const char *ntpServerName = "in.pool.ntp.org";
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[NTP_PACKET_SIZE]; // buffer to hold incoming and outgoing packets
WiFiUDP udp;
unsigned long epoch;
bool res;
double timeZoneCorrection = 5.30;
const int rebootEvery = 60 * 60 * 24;
const int flashButtonPin = 0;
const int dataPin = 2; // DS pin of 74HC595
const int clockPin = 5; // SH_CP pin of 74HC595
const int latchPin = 4; // ST_CP pin of 74HC595
const int oePin = 14; // OE pin of 74HC595 (connect to a PWM-capable pin)
const int ldrPin = A0; // LDR connected to A0
const int LEDpin = 13; // Pin connected to LED
bool Led = 0;
const byte segmentPatterns[10] = {
0b11111100, // 0
0b01100000, // 1
0b11011010, // 2
0b11110010, // 3
0b01100110, // 4
0b10110110, // 5
0b10111110, // 6
0b11100000, // 7
0b11111110, // 8
0b11110110 // 9
};
// Array to store the digits to be displayed
int digits[4] = {0b00010000, 0b00100000, 0b01000000, 0b10000000};
void displayDigit(int digit, int position)
{
// Disable all digits
digitalWrite(latchPin, LOW);
// For digits (set the current digit high and others low)
shiftOut(dataPin, clockPin, LSBFIRST, position);
// Send segment data to the shift registers
shiftOut(dataPin, clockPin, LSBFIRST, segmentPatterns[digit]);
// Latch the data
digitalWrite(latchPin, HIGH);
}
int hours, minutes, seconds;
void tick()
{
/*
* Executed every 1 second
*/
hours = ((epoch + 19800) % 86400L) / 3600;
minutes = ((epoch + 19800) % 3600) / 60;
seconds = (epoch + 19800) % 60;
// Add 1 second
epoch++;
Serial.println(hours);
Serial.println(minutes);
}
void Setiap500ms()
{
Led = !Led;
digitalWrite(LEDpin, Led);
if (Led == 1)
{
// Serial.println(hour * 100 + minute);
}
}
void adjustBrightness()
{
int ldrValue = analogRead(ldrPin);
// Serial.println(ldrValue);
int brightness = map(ldrValue, 100, 1023, 230, 0); // Map LDR value to PWM value (inverted)
analogWrite(oePin, brightness);
}
void updateDisplay()
{
displayDigit((int)(hours / 10), digits[0]);
displayDigit((int)(hours % 10), digits[1]);
displayDigit((int)(minutes / 10), digits[2]);
displayDigit((int)(minutes % 10), digits[3]);
}
void reboot()
{
disableDigits();
ESP.restart();
}
void disableDigits()
{
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, LSBFIRST, 0b00000000);
shiftOut(dataPin, clockPin, LSBFIRST, 0b00000000);
digitalWrite(latchPin, 1);
}
void wifinotconnected()
{
digitalWrite(LEDpin, 1);
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, LSBFIRST, 0b11110000);
shiftOut(dataPin, clockPin, LSBFIRST, 0b11100000);
digitalWrite(latchPin, 1);
}
void setup()
{
Serial.begin(115200);
// Set pins to output so you can control the shift register
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(oePin, OUTPUT); // OE pin for controlling brightness
pinMode(LEDpin, OUTPUT); // LED pin for blinking
pinMode(flashButtonPin, INPUT); // Pin for resetting wifi credentials
pinMode(ldrPin, INPUT);
udp.begin(localPort);
BrightnessTicker.attach_ms(10, adjustBrightness); // Adjust brightness every 250 milliseconds
if (WiFi.status() != WL_CONNECTED)
wifinotconnected();
if (!wifiMn.autoConnect("Esp Web Server", "12345678"))
{
Serial.println("Failed to connect and hit timeout");
ESP.reset();
delay(1000);
}
Serial.println("Conected to Wifi");
getDateTime();
Timer500ms.attach_ms(500, Setiap500ms);
tickerRefresh.attach(rebootEvery, reboot);
}
void loop()
{
if (digitalRead(flashButtonPin) == LOW)
{
wifiMn.resetSettings();
ESP.reset();
Serial.println("Wifi settings reset");
delay(1000);
}
updateDisplay();
}
/*
* The following code is based on the NTP Client example for ESP8266, more info on:
* https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266WiFi/examples/NTPClient
*/
void getDateTime()
{
disableDigits();
bool timeSuccess = false;
ticker.detach();
while (!timeSuccess)
{
// get a random server from the pool
WiFi.hostByName(ntpServerName, timeServerIP);
sendNTPpacket(timeServerIP); // send an NTP packet to a time server
// wait to see if a reply is available
delay(1000);
int cb = udp.parsePacket();
if (!cb)
{
Serial.println("no packet yet");
}
else
{
Serial.print("packet received, length=");
Serial.println(cb);
// We've received a packet, read the data from it
udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
// the timestamp starts at byte 40 of the received packet and is four bytes,
// or two words, long. First, esxtract the two words:
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
// combine the four bytes (two words) into a long integer
// this is NTP time (seconds since Jan 1 1900):
unsigned long secsSince1900 = highWord << 16 | lowWord;
Serial.print("Seconds since Jan 1 1900 = ");
Serial.println(secsSince1900);
// now convert NTP time into everyday time:
Serial.print("Unix time = ");
// Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
const unsigned long seventyYears = 2208988800UL;
// subtract seventy years:
epoch = (secsSince1900 - seventyYears);
// print Unix time:
Serial.println(epoch);
// print the hour, minute and second:
Serial.print("The UTC time is "); // UTC is the time at Greenwich Meridian (GMT)
Serial.print((epoch % 86400L) / 3600); // print the hour (86400 equals secs per day)
Serial.print(':');
if (((epoch % 3600) / 60) < 10)
{
// In the first 10 minutes of each hour, we'll want a leading '0'
Serial.print('0');
}
Serial.print((epoch % 3600) / 60); // print the minute (3600 equals secs per minute)
Serial.print(':');
if ((epoch % 60) < 10)
{
// In the first 10 seconds of each minute, we'll want a leading '0'
Serial.print('0');
}
Serial.println(epoch % 60); // print the second
timeSuccess = true;
// Enable ticker every second
ticker.attach(1, tick);
}
// wait x seconds before asking for the time again
delay(1000);
}
}
// send an NTP request to the time server at the given address
void sendNTPpacket(IPAddress &address)
{
Serial.println("sending NTP packet...");
// 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();
}
Setup Instructions
- Connect Hardware: Connect the ESP8266, shift registers, 7-segment display, LDR, and LED according to the provided pin configuration.
- Install Libraries: Ensure the required libraries are installed in your Arduino IDE.
- Configure WiFi: Update the ssid and pass variables with your WiFi credentials.
- Upload Code: Upload the provided code to the ESP8266.
- WiFi Setup: On first boot, connect to the "Esp Web Server" WiFi network and configure your WiFi settings via the web portal.
Pictures





Working Video
Conclusion
This ESP8266 NTP clock is a simple yet powerful project that demonstrates the capabilities of the ESP8266 in IoT applications. It provides accurate timekeeping, adjustable display brightness, and a reliable system with periodic reboots. Whether for educational purposes or practical use, this project serves as a great example of combining various hardware and software components into a cohesive and functional system.