ESP32 Bench
Boards: ESP32, S2, S3, C3, C6
Flash and monitor: Web Serial
← All projects

NTP internet clock

A desk clock that sets itself from the internet and handles daylight saving on its own. Big digits and the date on a small OLED.

Starter20 min115200 baud
Board
Fig. 1. Pins this project uses on the ESP32-DevKitC V4, 38 pin. USB connector at the bottom.

Wiring

FromTo boardNote
OLED VCC3V3
OLED GNDGND
OLED SDAGPIO 21
OLED SCLGPIO 22

Tested on this board

Not run on this board yet. Treat the wiring and code as a first draft.

Firmware, Arduino sketch for ESP32 Dev Module

// NTP clock: Wi-Fi sets the time, the TZ rule handles daylight saving.
#include <WiFi.h>
#include <Wire.h>
#include <time.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

const char* WIFI_SSID = "your-network";
const char* WIFI_PASS = "your-password";
// POSIX time zone rule. US Eastern shown; more examples in the project notes.
const char* TZ_RULE = "EST5EDT,M3.2.0,M11.1.0";

Adafruit_SSD1306 display(128, 64, &Wire, -1);
int lastMinute = -1;

void message(const char* text) {
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 28);
  display.print(text);
  display.display();
}

void setup() {
  Serial.begin(115200);
  Wire.begin(21, 22);
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println("SSD1306 not found at 0x3C");
    for (;;) delay(1000);
  }
  message("Joining Wi-Fi...");
  Serial.printf("wifi joining %s\n", WIFI_SSID);
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASS);
  while (WiFi.status() != WL_CONNECTED) delay(250);
  Serial.printf("wifi ok %s\n", WiFi.localIP().toString().c_str());

  message("Setting the time...");
  configTzTime(TZ_RULE, "pool.ntp.org", "time.google.com");
  struct tm now;
  while (!getLocalTime(&now, 10000)) Serial.println("waiting for NTP");
  char text[48];
  strftime(text, sizeof text, "%a %d %b %Y %H:%M:%S %Z", &now);
  Serial.printf("time synced: %s\n", text);
}

void loop() {
  struct tm now;
  if (!getLocalTime(&now, 100)) return;

  char hhmm[6], ss[3], date[20];
  strftime(hhmm, sizeof hhmm, "%H:%M", &now);
  strftime(ss, sizeof ss, "%S", &now);
  strftime(date, sizeof date, "%a %d %b %Y", &now);

  display.clearDisplay();
  display.setTextColor(SSD1306_WHITE);
  display.setTextSize(3);
  display.setCursor(4, 12);
  display.print(hhmm);
  display.setTextSize(2);
  display.setCursor(100, 19);
  display.print(ss);
  display.setTextSize(1);
  display.setCursor(4, 50);
  display.print(date);
  if (WiFi.status() != WL_CONNECTED) display.print(" *");  // still keeping time, just not syncing
  display.display();

  if (now.tm_min != lastMinute) {
    lastMinute = now.tm_min;
    char line[48];
    strftime(line, sizeof line, "%H:%M:%S %a %d %b %Y %Z", &now);
    Serial.println(line);
  }
  delay(200);
}

Parts

QuantityPartWhere to buy
1×ESP32 dev boardBuy at Amazon
1×0.96 inch SSD1306 OLED, I2C, address 0x3C
4×Jumper wires

Amazon buy links may include an Associates tag, and this site may earn a commission from qualifying Amazon purchases at no extra cost to you. Adafruit links are direct.

Libraries

WiFi (built in), Adafruit SSD1306, Adafruit GFX Library

Load it

  1. In the Arduino IDE, install the esp32 board package and pick the board named above the sketch.
  2. Install the libraries listed above from the Library Manager.
  3. Paste the sketch, choose the board's port and upload. Hold BOOT if the upload stalls at Connecting.
  4. Close the IDE's serial monitor, then open the bench here to watch the output.

Field notes

  • Change TZ_RULE for your time zone. Examples: Central US "CST6CDT,M3.2.0,M11.1.0", Pacific US "PST8PDT,M3.2.0,M11.1.0", UK "GMT0BST,M3.5.0/1,M10.5.0", Central Europe "CET-1CEST,M3.5.0,M10.5.0/3", Japan "JST-9".
  • The ESP32 re-syncs with the time servers about once an hour. If Wi-Fi drops, the clock keeps running on its own crystal and a * appears after the date.
  • Set WIFI_SSID and WIFI_PASS first. The ESP32 only joins 2.4 GHz networks.

Not tested yet

  • Not tested on hardware yet. Compiles for every board listed with Arduino-ESP32 core 3.3.12.

Built it? Send a build report with your board and what the serial port printed. Working reports become the "Tested on this board" entries above.