Build a Battery-Powered 7-Segment Clock with ESP32

Ever glance at a wall clock and think, “I could make that myself and toss in a splash of color”? With cheap LED segments and a tiny ESP32, that thought can become a real, ticking piece of art you can take anywhere. In this guide I’ll walk you through every step – from picking the right parts to wiring the display and getting the code to run on battery. By the end you’ll have a portable 7‑segment clock that you can stick on a bike, a shelf, or even a backpack.

Why a Battery‑Powered Segment Clock?

Most hobbyist clocks I see on forums are plugged into the wall, which limits where you can put them. A battery‑run version lets you place the clock wherever you need a quick glance at the time – no cords, no outlets. Plus, the ESP32’s low‑power sleep modes keep the draw down to a few milliamps, so a small Li‑Po pack can keep it alive for weeks.

Parts List

ItemWhy it matters
ESP32‑DevKitC (or any ESP32 board)Handles Wi‑Fi time sync and drives the segments
4‑digit common‑anode 7‑segment module (with decimal points)Gives you the classic “digital clock” look
2 × 220 Ω resistors (per segment)Limits current to protect the LEDs
1 × 10 kΩ pull‑up resistorKeeps the ESP32’s reset line stable
1 × Li‑Po 3.7 V 500 mAh battery + JST connectorPowers the whole thing
TP4056 charging board (optional)Lets you recharge the battery without taking it apart
Breadboard or perfboard, jumper wiresFor prototyping and final build
Small enclosure (plastic project box)Keeps everything tidy and portable

All of these parts are under $20 on most hobby sites, so the whole project stays budget‑friendly.

Understanding the Basics

7‑Segment Display

A 7‑segment display is just a set of seven tiny LEDs arranged in the shape of the number 8. Each segment lights up individually, and by turning the right combination on you can show any digit 0‑9. The “common‑anode” type shares a positive voltage on a common pin; you pull each segment low (to ground) to light it.

ESP32 and Wi‑Fi Time

The ESP32 has built‑in Wi‑Fi, so we can ask an NTP server for the current UTC time, then apply our local offset. This means the clock stays accurate without a real‑time‑clock (RTC) chip. The ESP32 also supports deep‑sleep, which we’ll use to save power between minute updates.

Wiring the Display

  1. Connect the common anode of the display to the 3.3 V rail of the ESP32.
  2. Add a 220 Ω resistor in series with each of the seven segment pins (A‑G) and the two decimal points. This keeps the LED current around 10 mA, safe for both the display and the ESP32’s GPIO pins.
  3. Wire each segment pin to a separate GPIO on the ESP32. I used pins 15, 2, 4, 16, 17, 5, 18 for A‑G and pins 19, 21 for the two dots.
  4. Connect the digit control pins (common pins for each of the four digits) to four more GPIOs (e.g., 22, 23, 25, 26). We’ll multiplex the digits, lighting one at a time fast enough that the eye sees all four.

A quick schematic looks like this (text version):

3.3V ----> Common Anode
GPIO15 --220Ω---> Segment A
GPIO2  --220Ω---> Segment B
...
GPIO18 --220Ω---> Segment G
GPIO19 --220Ω---> Decimal Point 1
GPIO21 --220Ω---> Decimal Point 2

GPIO22 --> Digit 1 (common cathode)
GPIO23 --> Digit 2
GPIO25 --> Digit 3
GPIO26 --> Digit 4

If you’re moving to a perfboard, keep the traces short and tidy – the ESP32’s pins are fragile.

Power Management

The ESP32 runs at 3.3 V, same as our display, so a single Li‑Po cell is perfect. Connect the battery’s + to the ESP32’s 3.3 V pin (or better, use the board’s VIN if it has a regulator). The TP4056 board sits between the battery and the ESP32, handling safe charging via USB. Remember to add a 10 kΩ pull‑up on the EN pin of the ESP32 if you use the TP4056’s “power‑good” output.

Coding the Clock

Below is a stripped‑down sketch that does the heavy lifting. It pulls the time from an NTP server, formats it, and multiplexes the display. Feel free to copy it into the Arduino IDE.

#include <WiFi.h>
#include <NTPClient.h>
#include <WiFiUdp.h>

// Wi‑Fi credentials
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASS";

// NTP setup
WiFiUDP udp;
NTPClient timeClient(udp, "pool.ntp.org", 0, 60000); // 0 offset, update every minute

// Segment pins (A‑G, DP)
const int segPins[9] = {15,2,4,16,17,5,18,19,21};
// Digit control pins
const int digPins[4] = {22,23,25,26};

// Digit patterns for 0‑9 (common‑anode, 1 = off, 0 = on)
const byte digitMap[10] = {
  0b11000000, // 0
  0b11111001, // 1
  0b10100100, // 2
  0b10110000, // 3
  0b10011001, // 4
  0b10010010, // 5
  0b10000010, // 6
  0b11111000, // 7
  0b10000000, // 8
  0b10010000  // 9
};

void setup() {
  // Init pins
  for (int i = 0; i < 9; i++) pinMode(segPins[i], OUTPUT);
  for (int i = 0; i < 4; i++) pinMode(digPins[i], OUTPUT);
  // Turn all digits off
  for (int i = 0; i < 4; i++) digitalWrite(digPins[i], HIGH);

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) delay(500);
  timeClient.begin();
  timeClient.setTimeOffset(-5 * 3600); // Example: EST (UTC‑5)
}

void loop() {
  timeClient.update();
  int hour = timeClient.getHours();
  int minute = timeClient.getMinutes();

  // Split into digits
  int d[4] = { hour / 10, hour % 10, minute / 10, minute % 10 };

  // Simple multiplexing
  for (int i = 0; i < 4; i++) {
    // Set segments
    byte pattern = digitMap[d[i]];
    for (int s = 0; s < 8; s++) {
      bool off = (pattern >> s) & 0x01;
      digitalWrite(segPins[s], off ? HIGH : LOW);
    }
    // Enable current digit
    digitalWrite(digPins[i], LOW);
    delay(2); // 2 ms per digit = 500 Hz refresh
    digitalWrite(digPins[i], HIGH);
  }

  // Sleep between minute changes to save power
  esp_sleep_enable_timer_wakeup(59000 * 1000ULL); // ~59 seconds
  esp_deep_sleep_start();
}

How the Code Works

  • Wi‑Fi & NTP: The ESP32 connects to your router, then asks pool.ntp.org for the current UTC time. Adjust the offset for your time zone.
  • Digit Mapping: Because we use a common‑anode display, a 0 on a segment pin turns the LED on, and a 1 turns it off. The digitMap array stores the pattern for each numeral.
  • Multiplexing: We light one digit at a time, fast enough that the human eye blends them together. The delay(2) gives a 500 Hz refresh, which looks steady.
  • Deep Sleep: After showing the time, the ESP32 goes into deep‑sleep for about a minute. It wakes, updates the time, and repeats. This cuts the average current to under 5 mA.

Putting It All Together

  1. Prototype on a breadboard – verify each segment lights correctly. Use the serial monitor to print the hour and minute values; that helps catch wiring mistakes.
  2. Transfer to perfboard – solder the resistors, wires, and ESP32. Keep the battery connector accessible.
  3. Enclose – drill holes for the display and a small vent for the battery. I used a clear acrylic box so the digits are visible from any angle.
  4. Test battery life – run the clock for a full day and note the voltage drop. With a 500 mAh cell you should see about 10–12 days of operation before recharging.

Tips & Tricks

  • Brightness control: Swap the 220 Ω resistors for 330 Ω if you find the display too bright at night. Lower current also means longer battery life.
  • Alternative time source: If Wi‑Fi isn’t reliable, add a cheap DS3231 RTC module. It only adds a few cents and gives you time even when offline.
  • Color fun: Red, green, or blue segment modules are all the same electrically. Pick a color that matches your room’s vibe.
  • Mounting: I love using double‑sided tape on the back of the box. It sticks to wood, metal, or plastic without drilling.

What I Learned

Building this clock reminded me why I love DIY electronics: a simple idea (show the time) becomes a playground for learning. The ESP32’s Wi‑Fi makes it easy to stay accurate, while the old‑school 7‑segment display gives a nostalgic feel. And yes, the battery life is real – I’ve been walking the clock around my workshop for a week and it’s still ticking.

If you try this project, feel free to experiment with different fonts (by wiring extra segments) or adding a button to switch between 12‑hour and 24‑hour mode. The sky’s the limit when you have a tiny microcontroller and a handful of LEDs.

Happy building!

Reactions