Zbotic Logo Zbotic Logo
  • Home
  • Shop
  • Sale
  • 3D Print Service
  • PCB Service
  • B2B
  • Blogs
  • Contact Us
0 0

View Wishlist Add all to cart

0 0
0 Shopping Cart
Shopping cart (0)
Subtotal: ₹0.00

View cartCheckout

  • Shop
  • About Us
  • Contact Us
  • Reseller
  • Blogs
020 69134444
1800 209 0998
[email protected]
Help Desk
Facebook Twitter Instagram Linkedin YouTube
Zbotic Logo Zbotic Logo
0 0

View Wishlist Add all to cart

0 0
0 Shopping Cart
Shopping cart (0)
Subtotal: ₹0.00

View cartCheckout

All departments
  • 3D Print Service
  • 3D Printer
  • Batteries & Chargers
  • Development Boards
  • Drone Parts
  • EBike parts
  • Sensor Modules
  • Electronic Components
  • Electronic Modules
  • IoT and Wireless
  • Mechanical Parts and Workbench Tools
  • Motors & Drivers & Pumps & Actuators
  • DIY and Robot Kits
  • Show more
  • Home
  • Shop
  • Sale
  • 3D Print Service
  • PCB Service
  • B2B
  • Blogs
  • Contact Us
Return to previous page
Home Display Modules & Screens

ESP32 Clock with NTP Server and OLED Display: Complete Build

ESP32 Clock with NTP Server and OLED Display: Complete Build

March 11, 2026 /Posted byJayesh Jain / 0

Building an ESP32 NTP clock with OLED display is one of the most satisfying beginner-to-intermediate projects you can complete in a weekend. Unlike RTC module-based clocks that drift over time and need manual setting, an NTP (Network Time Protocol) clock automatically synchronises with internet time servers, keeping perfect time indefinitely. Combined with a crisp OLED display and the ESP32’s built-in WiFi, you get an always-accurate, Indian Standard Time (IST) clock that costs under ₹350 in components. This complete guide covers everything from hardware assembly to final code with IST timezone support.

Table of Contents

  1. Components Required
  2. Wiring the OLED to ESP32
  3. Library Setup in Arduino IDE
  4. Complete NTP Clock Code with IST
  5. Display Design and Customisation
  6. Adding Temperature and Humidity Display
  7. Enclosure and Power Options
  8. Frequently Asked Questions

Components Required

Here is everything you need for the complete ESP32 NTP clock build:

  • ESP32 development board (NodeMCU ESP32, ESP32 DevKitC, or WROOM-32) — ~₹220
  • 0.96″ SSD1306 OLED display (128×64, I2C) — ~₹80
  • USB cable (Micro-USB or USB-C depending on your ESP32 board)
  • Jumper wires (4 female-to-female for I2C)
  • Optional: DHT11 or DHT20 sensor for temperature/humidity display
  • Optional: 3D printed or plastic enclosure

The entire project can be powered from a USB phone charger — perfect for desk or bedside placement. Total cost including ESP32 and display: under ₹350.

DHT20 SIP Packaged Temperature and Humidity Sensor

DHT20 SIP Temperature and Humidity Sensor

I2C DHT20 sensor in compact SIP package — add real-time temperature and humidity to your ESP32 NTP clock without using extra pins beyond I2C.

View on Zbotic

Wiring the OLED to ESP32

The 0.96″ SSD1306 OLED uses I2C — only 4 wires needed, making this one of the simplest possible displays to connect:

OLED Pin ESP32 Pin Notes
VCC 3.3V Use 3.3V, not 5V
GND GND Common ground
SDA GPIO 21 I2C data
SCL GPIO 22 I2C clock

GPIO 21 (SDA) and GPIO 22 (SCL) are the default I2C pins for the ESP32. The I2C address is typically 0x3C for these OLED modules, but some are 0x3D — check the back of your module for the A0 solder bridge.

Adding a DHT sensor: Connect DHT20 SDA/SCL to the same I2C bus (GPIO 21/22). Both the OLED and DHT20 share I2C without conflict since they have different addresses. For DHT11, connect the data pin to any free GPIO (e.g., GPIO 4).

Library Setup in Arduino IDE

You need the following libraries. Install them via Sketch → Include Library → Manage Libraries:

  1. Adafruit SSD1306 — OLED display driver
  2. Adafruit GFX Library — graphics primitives (auto-installed as dependency)
  3. NTPClient by Fabrice Weinberg — NTP time synchronisation
  4. WiFi — built into ESP32 Arduino core, no manual install needed
  5. Optional: DHT sensor library by Adafruit (for temperature display)

Also ensure the ESP32 board is installed in Arduino IDE. Go to File → Preferences and add this URL to Additional Board Manager URLs:

https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json

Then go to Tools → Board → Board Manager, search for “esp32” and install the Espressif package.

Complete NTP Clock Code with IST

Here is the complete, ready-to-use code for your ESP32 NTP OLED clock set to Indian Standard Time (UTC+5:30):

#include <WiFi.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// --- Configuration ---
const char* ssid     = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";

// IST = UTC + 5 hours 30 minutes = 19800 seconds
const long utcOffsetInSeconds = 19800;

// NTP server (India-friendly)
const char* ntpServer = "in.pool.ntp.org";

// OLED display settings
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET    -1
#define SCREEN_ADDRESS 0x3C

// --- Global objects ---
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, ntpServer, utcOffsetInSeconds, 60000);

// --- Helper: zero-pad single digit numbers ---
String zeroPad(int num) {
  return (num < 10) ? "0" + String(num) : String(num);
}

// --- Day name lookup ---
const char* dayNames[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
const char* monthNames[] = {"", "Jan", "Feb", "Mar", "Apr", "May", "Jun",
                             "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};

void setup() {
  Serial.begin(115200);
  
  // Initialise display
  if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println("SSD1306 init failed!");
    for(;;);  // Halt
  }
  display.clearDisplay();
  display.setTextColor(WHITE);
  
  // Show connecting screen
  display.setTextSize(1);
  display.setCursor(10, 20);
  display.println("Connecting WiFi...");
  display.setCursor(10, 35);
  display.println(ssid);
  display.display();
  
  // Connect to WiFi
  WiFi.begin(ssid, password);
  int attempts = 0;
  while (WiFi.status() != WL_CONNECTED && attempts < 30) {
    delay(500);
    Serial.print(".");
    attempts++;
  }
  
  if (WiFi.status() == WL_CONNECTED) {
    Serial.println("nWiFi connected!");
    // Start NTP client
    timeClient.begin();
    timeClient.update();
    
    display.clearDisplay();
    display.setCursor(15, 25);
    display.println("NTP Synced!");
    display.display();
    delay(1500);
  } else {
    // WiFi failed — show error but continue
    display.clearDisplay();
    display.setCursor(5, 20);
    display.println("WiFi Failed!");
    display.setCursor(5, 35);
    display.println("Check credentials");
    display.display();
    delay(3000);
  }
  
  // Reduce brightness for long-running use
  display.ssd1306_command(SSD1306_SETCONTRAST);
  display.ssd1306_command(50);  // Reduced from max 255
}

void drawClock() {
  timeClient.update();
  
  int hours   = timeClient.getHours();
  int minutes = timeClient.getMinutes();
  int seconds = timeClient.getSeconds();
  int dayOfWeek = timeClient.getDay();  // 0=Sunday
  
  display.clearDisplay();
  
  // --- Large time display (centre) ---
  display.setTextSize(3);
  display.setCursor(4, 18);
  display.print(zeroPad(hours));
  display.print(":");
  display.print(zeroPad(minutes));
  
  // Blinking colon (blinks every second)
  display.setTextSize(2);
  display.setCursor(112, 22);
  if (seconds % 2 == 0) display.print(":");
  
  // --- Seconds bar ---
  int barWidth = map(seconds, 0, 59, 0, 128);
  display.fillRect(0, 56, barWidth, 8, WHITE);
  
  // --- Day and date header ---
  display.setTextSize(1);
  display.setCursor(0, 2);
  display.print(dayNames[dayOfWeek]);
  display.setCursor(50, 2);
  display.print("IST  ");
  
  // WiFi signal indicator
  if (WiFi.status() == WL_CONNECTED) {
    display.fillRect(120, 0, 8, 8, WHITE);
    display.setTextColor(BLACK);
    display.setCursor(121, 0);
    display.print("W");
    display.setTextColor(WHITE);
  }
  
  display.display();
}

void loop() {
  drawClock();
  delay(1000);
}

The code uses in.pool.ntp.org — the NTP pool for India, which routes your sync requests to geographically close servers for low latency. The UTC offset of 19800 seconds (5 hours 30 minutes = IST) handles the Indian timezone automatically.

Display Design and Customisation

The code above uses large size-3 text for the time display. Here are several customisation options:

12-Hour Format with AM/PM

bool isPM = (hours >= 12);
int hours12 = hours % 12;
if (hours12 == 0) hours12 = 12;

display.print(zeroPad(hours12));
display.print(":");
display.print(zeroPad(minutes));

display.setTextSize(1);
display.setCursor(110, 28);
display.print(isPM ? "PM" : "AM");

Custom Fonts with U8g2

For a more polished look, use the U8g2 library which includes dozens of fonts including large 7-segment style numerals that look like a real digital clock:

#include <U8g2lib.h>
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0);

// In setup:
u8g2.begin();
u8g2.setFont(u8g2_font_logisoso28_tf);  // 7-segment style, 28px

// In loop:
u8g2.clearBuffer();
u8g2.drawStr(0, 40, timeString.c_str());
u8g2.sendBuffer();

Pixel Shifting for Burn-In Prevention

// Add to drawClock: shift text by 0-2 pixels each minute
int shift = (minutes % 3);  // 0, 1, or 2 pixels
display.setCursor(4 + shift, 18 + shift);
// ... draw time as before

Adding Temperature and Humidity Display

Extend the clock with a DHT sensor to show current temperature and humidity — very useful for Indian summers:

#include "DHT.h"
#define DHTPIN 4
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);

float temperature, humidity;
unsigned long lastSensorRead = 0;

void readSensor() {
  // Read sensor only every 5 seconds (DHT11 limitation)
  if (millis() - lastSensorRead > 5000) {
    temperature = dht.readTemperature();
    humidity    = dht.readHumidity();
    lastSensorRead = millis();
  }
}

// In drawClock(), after main time display:
readSensor();
display.setTextSize(1);
display.setCursor(0, 48);
display.print(temperature, 1);
display.print("C  ");
display.print(humidity, 0);
display.print("%RH");
DHT11 Temperature And Humidity Sensor Module with LED

DHT11 Temperature and Humidity Sensor Module with LED

Add live temperature and humidity data to your ESP32 NTP clock display — the onboard LED confirms sensor activity at a glance.

View on Zbotic

GY-BME280-5V Temperature and Humidity Sensor

GY-BME280-5V Temperature, Humidity and Pressure Sensor

5V-compatible BME280 covering temperature, humidity and barometric pressure — upgrade your ESP32 NTP clock into a complete weather station on one display.

View on Zbotic

Enclosure and Power Options

Making the project look presentable is half the fun. Here are practical options for Indian makers:

Enclosure Ideas

  • Cardboard box: Quick and zero-cost — cut holes for the display and USB port. Decorate with paper or craft materials.
  • 3D printed case: Thingiverse has dozens of ESP32 + 0.96″ OLED case designs. Print in PLA at any local 3D printing shop in India for ₹100–₹200.
  • Acrylic box: Available from local hardware stores or cut to size at an acrylic fabrication shop. Looks very professional.
  • Old phone case: Some Nokia or old smartphone cases can be repurposed with creative cutting.

Power Supply

  • USB power bank: Completely portable clock — runs for 10–20 hours on a 5000 mAh bank
  • 5V wall adapter: Plug into any USB charger for a permanent desk clock
  • Solar + LiPo: For outdoor use, a 5V solar panel + TP4056 charger + 18650 LiPo cell gives full off-grid operation

Power consumption tip: The ESP32 in WiFi active mode draws about 80–150 mA. To save power, use deep sleep between time syncs: sync NTP every hour, then sleep with only a basic time counter running. The display itself draws 20–30 mA at moderate brightness.

LM35 Temperature Sensors

LM35 Temperature Sensors

Classic analog temperature sensor — a budget-friendly option for adding temperature to your ESP32 clock project using the ADC input without extra libraries.

View on Zbotic

Frequently Asked Questions

Q1: My ESP32 connects to WiFi but the time shows wrong — how do I fix IST timezone?

IST is UTC+5:30, which is 5 × 3600 + 30 × 60 = 19800 seconds. In the NTPClient constructor, make sure the third parameter is exactly 19800: NTPClient timeClient(ntpUDP, "in.pool.ntp.org", 19800, 60000);. Alternatively, use the ESP32’s built-in configTime(19800, 0, "in.pool.ntp.org") which also handles daylight saving correctly (India does not observe DST, so the second parameter is 0).

Q2: The NTP time drifts when WiFi disconnects — how to maintain time?

The ESP32’s internal RTC keeps time using its crystal oscillator, which drifts about 5–30 seconds per day. To minimise impact: sync NTP on startup, then re-sync whenever WiFi reconnects (use WiFi.onEvent() callback). For more accurate offline timekeeping, add a DS3231 RTC module — it drifts less than 2 seconds per month.

Q3: Can I use ESP8266 (NodeMCU) instead of ESP32 for this project?

Yes — the wiring and code are nearly identical. Replace #include <WiFi.h> with #include <ESP8266WiFi.h>. The SSD1306 I2C pins on NodeMCU v3 are SDA=D2 (GPIO4) and SCL=D1 (GPIO5). NTPClient library works identically. ESP8266 is slightly cheaper but has less RAM — avoid large U8g2 font sizes.

Q4: How do I add a buzzer alarm to the clock?

Connect a passive buzzer to any GPIO (e.g., GPIO 25). Add alarm time variables and check them in your loop: if hours == alarmHour && minutes == alarmMinute && seconds == 0, call tone(25, 1000, 500) to beep. For a user-configurable alarm, add two buttons connected to GPIOs to increment/decrement the alarm hour and minute.

Q5: Is in.pool.ntp.org reliable in India?

Yes — the NTP Pool Project has dedicated Indian servers. You can also use pool.ntp.org (global), time.google.com, or time.cloudflare.com as alternatives. For best reliability, specify multiple servers: use the configTime approach with 2–3 server arguments: configTime(19800, 0, "in.pool.ntp.org", "time.google.com", "pool.ntp.org");

Build Your ESP32 NTP Clock This Weekend

An ESP32 NTP clock with OLED display is the perfect weekend project — under ₹350 in parts, perfectly accurate Indian Standard Time, and a great learning experience with WiFi, I2C, and display programming all in one build.

Get all the components you need — ESP32 boards, OLED displays, sensors, and more — at Zbotic.in, India’s favourite electronics components store with competitive prices and fast delivery across India.

Tags: ESP32 NTP Clock, ESP32 Projects India, ESP32 WiFi Clock, NTP Server Arduino, OLED Display Project
Share Post
  • Facebook
  • Linkedin
  • Whatsapp
Robot IMU Sensor Fusion: Kalma...
blog robot imu sensor fusion kalman filter for stable orientation 597676
blog nrf24l01 multiple receivers hub and spoke network arduino 597678
NRF24L01 Multiple Receivers: H...

Related posts

Svg%3E
Read more

Multi-Display Sync: Run Same Content on Multiple Screens

April 1, 2026 0
Table of Contents When You Need Multiple Synchronised Displays Communication Protocols for Display Sync I2C Multi-Display Architecture SPI Daisy-Chain Approach... Continue reading
Svg%3E
Read more

Display Brightness Control: Ambient Light Auto-Adjust

April 1, 2026 0
Table of Contents Why Auto-Brightness Matters Light Sensors: LDR, BH1750, TSL2561 PWM Brightness Control Basics Implementing Auto-Brightness for OLED Auto-Brightness... Continue reading
Svg%3E
Read more

LCD Menu System: Multi-Level Navigation with Encoder

April 1, 2026 0
Table of Contents Why Build a Menu System Hardware: LCD + Rotary Encoder Menu Architecture Design Implementing the Menu Engine... Continue reading
Svg%3E
Read more

LED Running Text: Single Line Scrolling Marquee

April 1, 2026 0
Table of Contents Applications for Scrolling Marquee Displays Hardware Options: Dot Matrix vs LED Panel Building with MAX7219 Cascaded Modules... Continue reading
Svg%3E
Read more

Prayer Time Display: Mosque and Temple Timer India

April 1, 2026 0
Table of Contents The Need for Automated Prayer Time Displays Calculating Prayer Times Programmatically Display Options for Places of Worship... Continue reading

Add comment Cancel reply

Your email address will not be published. Required fields are marked

Facebook Twitter Instagram Pinterest Linkedin Youtube

Get the latest deals and more.

Download on Google Play Download on the App Store

Call us: 020 69134444 / 1800 209 0998

Monday - Saturday 09:30 AM - 06:00 PM
For Technical Supports Email: [email protected]
For Sales / Enquiries Email: [email protected]

  • My Account

    • Cart

    • Wishlist

    • Checkout

    • My Orders

    • Track Order

    • My Account

  • Information

    • FAQs

    • Blogs

    • Career

    • About Us

    • Contact Us

    • Payment Options

  • Policies

    • Privacy Policy

    • Terms & Conditions

    • GST Input Tax Credit

    • Shipping Return Policy

    • E-Waste Collection Points

    • Our Sitemap

© Zbotic.in is registered trademark of Moxie Supply Pvt Ltd – All Rights Reserved
Login
Use Phone Number
Use Email Address
Not a member yet? Register Now
Reset Password
Use Phone Number
Use Email Address
Register
Already a member? Login Now