A clock that sets itself
An ESP32, a clock panel and four wires. The time comes from the internet, the colon blinks once a second, and the display shows four dashes until the time is real — which matters more than it sounds.
What the sketch is doing
Three things, and only one of them is about the display.
The ESP32 has no battery-backed clock, so it wakes up in 1970 every time. It joins your network, asks a time server what time it is, and the C library keeps count from there.
configTzTime takes a POSIX timezone string rather than an offset in seconds.
The string carries the daylight-saving rules, so the clock changes itself in the
right week without you reflashing anything in October.
Then the display: hours × 100 + minutes is the number, and the colon is one bit.
The face
0b01000000 lights the colon between them. Drag the slider through midnight with leading zeros off to see why they are on.Drag through midnight with leading zeros off and you can watch both failures
happen: 00:05 arrives as the number 5 and prints as a bare 5 with a stray colon,
and 00:00 loses the colon entirely. With leading zeros on, neither can happen —
which is why the sketch passes true.
Twelve-hour time is the opposite: the hour is never 0, and leading zeros off gives you 9:05 rather than 09:05.
int h = t.tm_hour % 12; if (h == 0) h = 12;
display.showNumberDecEx(h * 100 + t.tm_min, COLON, false);Why the colon blinks
Partly because clocks do. Mostly because it is the only thing on a finished clock that says the sketch is still running.
A display holds its four bytes with no help from your board. If the ESP32 crashes, loses Wi-Fi in a way that blocks, or sits in a watchdog reset loop, the time on the panel simply stops changing — and a clock showing 14:32 looks exactly as convincing at half past three. A colon that blinks once a second is a heartbeat you can see from the doorway.
The dashes do the same job at the other end. Until the year is past 2020 the sketch refuses to show a time at all, because a confidently displayed 00:00 that happens to be 1970 is worse than an obviously blank display.
Making it live somewhere
Two changes turn this from a sketch into a clock on a shelf.
Drop the brightness at night — read t.tm_hour and call setBrightness(0)
after nine and setBrightness(5) in the morning. Remember that it is sent with
the next write, which here is 200 ms away.
And power it from a USB charger rather than a computer. Nothing in the sketch needs the serial port after the IP address is printed, and an ESP32 with a clock panel is a few hundred milliamps at most — well inside any phone charger.
The code
A 24-hour clock on an ESP32. Put your network name and password at the top, and your own timezone string — the one here is Melbourne, and it carries the daylight-saving dates so the clock changes itself in the right week.
// A clock that sets itself: ESP32 + a TM1637 clock panel, time over Wi-Fi.
//
// Wiring, display to board:
// Display GND -> board GND
// Display VCC -> board 3V3 (not 5V: the board's pull-ups would then
// hold CLOCK and DATA at 5 V against pins
// rated for 3.3 V)
// Display CLOCK -> GPIO 18
// Display DATA -> GPIO 19
//
// Arduino IDE: ESP32 board support installed, board "ESP32 Dev Module",
// and "TM1637" by Avishay Orpaz from the Library Manager. Serial Monitor
// at 115200.
#include <WiFi.h>
#include <time.h>
#include <TM1637Display.h>
#define CLOCK_PIN 18
#define DATA_PIN 19
#define COLON 0b01000000 // bit 7 of the second digit
const char *SSID = "your-ssid";
const char *PASSWORD = "your-password";
// POSIX timezone: the offset and the two dates daylight saving changes on,
// so the board handles the switch itself. Replace with your own.
const char *TZ = "AEST-10AEDT,M10.1.0,M4.1.0/3";
TM1637Display display(CLOCK_PIN, DATA_PIN);
// Shown until the time is real. An old or wrong time looks identical to a
// right one; four dashes do not.
const uint8_t DASHES[] = { 0x40, 0x40, 0x40, 0x40 };
void setup() {
Serial.begin(115200);
display.setBrightness(4);
display.setSegments(DASHES);
WiFi.begin(SSID, PASSWORD);
while (WiFi.status() != WL_CONNECTED) delay(250);
Serial.println(WiFi.localIP());
configTzTime(TZ, "pool.ntp.org", "time.nist.gov");
}
void loop() {
struct tm t;
if (!getLocalTime(&t, 100) || t.tm_year + 1900 < 2020) {
display.setSegments(DASHES); // no time yet
delay(500);
return;
}
// Leading zeros on: without them, midnight sends the number 0 and this
// version of the library drops the colon along with the blank digits.
display.showNumberDecEx(t.tm_hour * 100 + t.tm_min,
(t.tm_sec % 2) ? COLON : 0,
true);
delay(200);
}The year check is the real test for whether the time has arrived: getLocalTime returns true as soon as the clock has any time at all, and on a cold boot that time is 1970. Until the year looks plausible the display shows four dashes, which is honest in a way that a wrong time is not.
When it does not work
Either Wi-Fi never connected or NTP never answered. Check the serial monitor: the sketch prints the board's IP address once it is on the network. If the IP appears and the dashes stay, NTP is being blocked — it is UDP port 123 outbound, which plenty of guest and corporate networks drop. Most routers run a time server on the gateway address instead.
That is a fixed offset instead of a timezone. A POSIX TZ string like the one in the sketch carries the two switch dates, so the board changes itself. gmtOffset plus daylightOffset is correct for one half of the year and wrong for the other.
Check the panel first — a digit panel has no colon, only points. If it is a clock panel, check the mask is 0b01000000 and not 0b10000000, and that leading zeros are on.
The display holds whatever it was last sent, so a crashed sketch leaves a perfectly readable frozen clock. That is what the blinking colon is really for: a clock whose colon has stopped blinking is a clock whose sketch has stopped running.
3.3 V is not enough for blue or white. Use a red, orange, yellow or green panel on an ESP32, or feed the display 5 V with a level converter in the two signal wires.
The same display with a point instead of a colon, and the arithmetic that puts the point in the right place.
A voltmeter readout →Edit this page — content/books/tm1637-display/a-clock-that-sets-itself.mdx
Questions about this product
See what other owners have asked, and read their solutions.
This page covers several products. Choose yours to see the right discussions.
Discuss this article
Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.