ESP32 WiFi New Year Countdown Timer

by Rainier-PS in Circuits > Arduino

59 Views, 0 Favorites, 0 Comments

ESP32 WiFi New Year Countdown Timer

New Year Countdown Timer Thumbnail.png
New Year Countdown Timer.jpg

In this project, we will build a WiFi-synchronized New Year countdown timer using an ESP32, a 16×2 LCD, a buzzer, and the ESP32’s built-in LED.

Unlike many clocks or countdown timers, this project does NOT need a real-time clock (RTC) module. Instead, the ESP32 connects to the internet and automatically gets the correct date and time using NTP (Network Time Protocol). This makes the project accurate, simple, and beginner-friendly.

The timer continuously shows the current time and counts down to New Year. As midnight approaches, the buzzer beeps faster and the LED flashes faster. When the countdown reaches zero, the LCD displays a celebration message, the buzzer plays a long tone, and the LED stays on.

A built-in test mode lets you simulate the final countdown in just a few seconds, so you don’t need to wait until the real New Year to test your project.

What this project does

  1. Connects to WiFi automatically
  2. Gets the correct current time from the internet (NTP)
  3. Displays the current local time with an approximate tenths-of-a-second display
  4. Displays a live countdown to the New Year in seconds
  5. Beeps faster as the countdown approaches zero
  6. Flash the built-in ESP32 LED in sync with the buzzer
  7. Displays “HAPPY NEW YEAR!” at midnight
  8. Includes a test mode for quick testing and demonstrations

What you will learn

  1. How the ESP32 connects to WiFi
  2. How internet time (NTP) works
  3. How to use a 16×2 LCD with Arduino
  4. How ESP32 GPIO input and output pins work
  5. How to use millis() instead of delay()
  6. How to read and understand real Arduino code

This guide is written for beginners, so everything is explained step by step.

Github Repository Link: Link

Supplies

Supplies_New Year Countdown.png

Electronic Parts

  1. ESP32 development board
  2. 16×2 LCD (HD44780 compatible)
  3. Buzzer (passive recommended)
  4. Potentiometer (for LCD contrast)
  5. Breadboard
  6. Jumper wires
Note: This project utilizes the ESP32’s built-in LED on GPIO 2, eliminating the need for an external LED.

Tools

  1. Computer with Arduino IDE installed
  2. USB cable
  3. WiFi connection (2.4 GHz)

What each part does

  1. ESP32: The brain of the project
  2. LCD: Displays time and countdown text
  3. Potentiometer: Adjusts the LCD contrast to make the text visible.
  4. Buzzer: Creates sound effects

Understanding the Big Idea

Step-1.png

Before wiring anything, let’s understand how the project works:

  1. The ESP32 connects to your WiFi network.
  2. It requests the current date and time from an NTP server.
  3. The code calculates how many seconds remain until the New Year.
  4. The LCD continuously shows:
  5. The current time
  6. The remaining seconds
  7. As the countdown approaches zero:
  8. The buzzer beeps faster
  9. The built-in LED flashes faster
  10. At exactly midnight:
  11. The LCD shows “HAPPY NEW YEAR!”
  12. The buzzer plays a long tone
  13. The LED stays ON
Because the ESP32 gets time from the internet, the countdown stays accurate without manual adjustment.

Understanding ESP32 Pins

ESP32 pins are called GPIO pins. Each pin can be used as:

  1. OUTPUT – sends signals (buzzer, LED)
  2. INPUT – reads signals (button or jumper)

In this project:

  1. Buzzer → OUTPUT
  2. Built-in LED (GPIO 2) → OUTPUT
  3. Test pin (GPIO 34) → INPUT
Important: GPIO 34 is input-only and does NOT have internal pull-up or pull-down resistors. This means it must be driven HIGH externally (3.3V) using a button, jumper wire, or external resistor to activate test mode.

Wiring the Circuit

In this step, we will connect all the components to the ESP32 using jumper wires and a breadboard. Take your time here. Most problems in beginner projects come from wiring mistakes.

Connecting the LCD (16×2 Display)

Use jumper wires to connect the LCD to the ESP32. The LCD is used in 4-bit mode, which means we only use four data pins instead of eight.

  1. LCD VSS → ESP32 GND
  2. LCD VDD → ESP32 3.3V (recommended for ESP32)
  3. LCD RW → ESP32 GND

Now connect the LCD control and data pins:

  1. LCD RS → ESP32 GPIO 13
  2. LCD EN → ESP32 GPIO 33
  3. LCD D4 → ESP32 GPIO 14
  4. LCD D5 → ESP32 GPIO 27
  5. LCD D6 → ESP32 GPIO 26
  6. LCD D7 → ESP32 GPIO 25

If your LCD has a backlight:

  1. A (LED+) → 5V through a resistor
  2. K (LED−) → GND

Connecting the Buzzer

Use jumper wires to connect the buzzer to the ESP32:

  1. Buzzer positive (+) → ESP32 GPIO 32
  2. Buzzer negative (−) → ESP32 GND
Passive buzzer: Recommended. The tone() function controls pitch and timing.
Active buzzer: Will still beep, but pitch control is ignored.

Test Mode

  1. GPIO 34 → Button or jumper → 3.3V
  2. When GPIO 34 reads HIGH, test mode starts.
  3. You can use a push button or simply touch a jumper wire to 3.3V.

Final Wiring Check

Before moving on:

  1. Double-check every connection
  2. Make sure all GND connections share the same ground
  3. Ensure no wires are loose or shorted

Once everything is connected correctly, you are ready to upload the code and test the project.

Installing Arduino IDE and ESP32 Support

  1. Install the Arduino IDE
  2. Open Preferences
  3. Add this URL to “Additional Board Manager URLs”:
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
  1. Open Boards Manager
  2. Install ESP32 by Espressif Systems
  3. Select your ESP32 board and COM port

Libraries Used

At the top of the code, you will see:

#include <LiquidCrystal.h>
#include <WiFi.h>
#include <time.h>

What is a library?

A library is pre-written code that makes complex tasks easier.

  1. LiquidCrystal controls the LCD
  2. WiFi handles wireless connections
  3. time.h works with dates and times

Arduino Program Structure

Every Arduino program has two main functions:

void setup() {
}
Runs once when the board starts.
void loop() {
}
Runs repeatedly forever.

Global variables are declared outside these functions so both can use them.

Pin Definitions and Constants

#define buzzerPin 32
#define ledPin 2
#define TEST_PIN 34

Using named pins makes the code easier to read and change later.

LCD Setup

LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
lcd.begin(16, 2);

This tells Arduino:

  1. Which pins the LCD uses
  2. That the LCD has 16 columns and 2 rows


To display text:

lcd.setCursor(0, 0);
lcd.print("Hello");

Connecting to WiFi

WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}

This keeps checking until the ESP32 is connected. The while loop repeats as long as the condition is true.

Getting Time From the Internet

configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);

Important concepts

  1. NTP gives the current time in seconds since 1970
  2. GMT offset adjusts for your time zone (currently set to UTC+7 in the code)
  3. time_t stores time as seconds

The code waits until a valid time is received before continuing.

Calculating the Next New Year

The code uses a structure called tm:

struct tm t = {};

This structure stores:

  1. Year
  2. Month
  3. Day
  4. Hour
  5. Minute
  6. Second
The target New Year date is currently hard-coded to January 1, 2026 for simplicity.

Countdown Logic

long remaining = targetTime - now;
  1. The remaining time is calculated by subtracting the current time from the target time.
  2. The result is the number of seconds left until the New Year.
  3. This value updates continuously while the ESP32 is running.

Displaying Time and Countdown

snprintf(line1, sizeof(line1), "%02d:%02d:%02d.%1d", ...);

The LCD shows:

  1. Current time (hours, minutes, seconds, approximate tenths)
  2. Countdown in seconds
snprintf() is used to safely format text before printing to the LCD. This prevents display glitches and memory issues.

Sound and LED Timing

The project uses millis() instead of delay().

This allows:

  1. LCD updates
  2. Buzzer beeps
  3. LED flashing

to happen at the same time without freezing the program.

As the countdown approaches zero, the beep interval becomes shorter to build excitement.

Test Mode

Test mode enables you to test the final countdown instantly.

  1. Pull GPIO 34 HIGH
  2. A 5-second countdown begins (hard-coded in the program)
  3. A “T” indicator appears on the LCD
  4. The buzzer and LED behave exactly like the real countdown
Releasing the pin exits test mode.

The Final Moment

When the countdown reaches zero:

  1. The LCD displays “HAPPY NEW YEAR!”
  2. The buzzer plays a long tone
  3. The built-in LED turns ON and stays ON

A safety flag prevents this from triggering more than once.

Uploading and Testing

  1. Upload the code
  2. Open Serial Monitor (optional)
  3. Watch the LCD update
  4. Manually jumper GPIO34 to 3.3V to enter test mode

Troubleshooting

No WiFi

  1. Check the SSID and password
  2. Make sure the network is 2.4 GHz

LCD shows nothing

  1. Check wiring
  2. Adjust the contrast potentiometer

Button does not work

  1. Ensure GPIO 34 reaches 3.3V
  2. Double-check the pin number
  3. Verify the test mode jumper or button module

Improvement and Customization Ideas

You can improve or adjust this project by modifying some things, such as:

  1. Change the time zone
  2. Add an external LED or LED strip
  3. Replace the LCD with an OLED or I2C LCD
  4. Play a melody instead of a single tone
  5. Add an enclosure or case
  6. Add buttons to set custom countdown dates (e.g., birthday or other holidays)

Conclusion

20251219_164135_0000.png

Congratulations! You have built a fully automatic, WiFi-synchronized New Year countdown timer using an ESP32. This project demonstrates real-world microcontroller concepts such as WiFi connectivity, internet time, non-blocking code, and display control. You can reuse and expand this project for other countdowns or clock-based ideas.


Happy tinkering and happy New Year!


Rainier P.S.

Personal Website: Link | GitHub: Link