Close Menu
  • Articles
    • Learn Electronics
    • Product Review
    • Tech Articles
  • Electronics Circuits
    • 555 Timer Projects
    • Op-Amp Circuits
    • Power Electronics
  • Microcontrollers
    • Arduino Projects
    • STM32 Projects
    • AMB82-Mini IoT AI Camera
    • BLE Projects
  • IoT Projects
    • ESP8266 Projects
    • ESP32 Projects
    • ESP32 MicroPython
    • ESP32-CAM Projects
    • LoRa/LoRaWAN Projects
  • Raspberry Pi
    • Raspberry Pi Projects
    • Raspberry Pi Pico Projects
    • Raspberry Pi Pico W Projects
  • Electronics Calculator
Facebook X (Twitter) Instagram
  • About Us
  • Disclaimer
  • Privacy Policy
  • Contact Us
  • Advertise With Us
Facebook X (Twitter) Instagram Pinterest YouTube LinkedIn
How To Electronics
  • Articles
    • Learn Electronics
    • Product Review
    • Tech Articles
  • Electronics Circuits
    • 555 Timer Projects
    • Op-Amp Circuits
    • Power Electronics
  • Microcontrollers
    • Arduino Projects
    • STM32 Projects
    • AMB82-Mini IoT AI Camera
    • BLE Projects
  • IoT Projects
    • ESP8266 Projects
    • ESP32 Projects
    • ESP32 MicroPython
    • ESP32-CAM Projects
    • LoRa/LoRaWAN Projects
  • Raspberry Pi
    • Raspberry Pi Projects
    • Raspberry Pi Pico Projects
    • Raspberry Pi Pico W Projects
  • Electronics Calculator
How To Electronics
Home » Stopwatch using ESP32 & LCD with Start, Stop & Reset Button
ESP32 Projects

Stopwatch using ESP32 & LCD with Start, Stop & Reset Button

Mamtaz AlamBy Mamtaz AlamUpdated:March 23, 20254 Mins Read
Share Facebook Twitter LinkedIn Telegram Reddit WhatsApp
ESP32 Stopwatch Timer
Share
Facebook Twitter LinkedIn Pinterest Email Reddit Telegram WhatsApp

Stopwatch Using ESP32 & LCD – Start Stop Reset Button

In this project, we have designed a simple stopwatch using an ESP32 and an I²C LCD display with start, stop, and reset functionalities. A stopwatch typically requires two primary modes—a start mode and a stop mode—to function properly. In our design, the start button is used to initiate or resume the timing, while the stop button pauses the timer. Additionally, if the stop button is pressed again when the timer is paused, the system resets, making it ready for a new timing session.

The ESP32 code uses the Arduino framework’s millis() function to accurately track time in milliseconds. This function allows the system to measure elapsed time with high precision, ensuring 100% accuracy for the stopwatch’s timing functions. Although the ESP32 is capable of displaying up to four digits after the decimal point, our implementation simplifies the output by showing only three digits for clarity on the LCD.

Earlier we made StopWatch using Arduino. You can also make Stopwatch Using Digit using Segment Display which is more cost effective and cheaper compared to LCD version.


Components Required

Following are the components that are required to make a stopwatch using the ESP32 Microcontroller. You can purchase all these components from the Amazon or AliExpress links.

S.N.Components NameQuantityPurchase Link
1ESP32 Board1Amazon | AliExpress
216x2 I2C LCD Display1Amazon | AliExpress
3Push Button Switch2Amazon | AliExpress
4Connecting Wires10Amazon | AliExpress
5Breadboard1Amazon | AliExpress




Circuit Diagram & Hardware Connections

Here is a connection diagram for a Stopwatch designed using an ESP32, a 16×2 I²C LCD Display, and two push-button switches.

Stopwatch ESP32 Circuit

Connect the push buttons to the ESP32 digital pins 18 and 19. Digital pin 18 is used for the start button, while digital pin 19 is used for the stop or reset button.

For the 16×2 I²C LCD Display, the wiring is simplified compared to a parallel connection. Connect the LCD’s SDA pin to the ESP32’s SDA line (commonly GPIO21) and the SCL pin to the ESP32’s SCL line (commonly GPIO22). Also, connect the LCD’s VCC pin to the 5V supply and the GND pin to the ESP32’s ground.

Stopwatch ESP32 Connection

Assemble the circuit on a breadboard as shown in the image above, ensuring that all connections are secure for proper operation of the stopwatch.




Source Code/Program:

Here is the C++ code that functions as a ESP32 Simple Stopwatch that allows the user to start, pause, and reset timing events with two physical buttons. For this code, you need to install I2C LCD Library for LCD Display.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
 
// Initialize the I²C LCD at address 0x27 with 16 columns and 2 rows.
LiquidCrystal_I2C lcd(0x27, 16, 2);
 
// Button pin definitions for the ESP32.
const int startButtonPin = 18;  // Start/resume button
const int stopButtonPin  = 19;   // Stop/pause/reset button
 
// Timer states.
enum TimerState { IDLE, RUNNING, PAUSED };
TimerState timerState = IDLE;
 
unsigned long startTime = 0;    // Time when the timer is started/resumed.
unsigned long elapsedTime = 0;  // Accumulated elapsed time in milliseconds.
 
void setup() {
  lcd.init();
  lcd.backlight();
  lcd.clear();
 
  Serial.begin(115200);
 
  // Setup button pins with internal pull-ups.
  pinMode(startButtonPin, INPUT_PULLUP);
  pinMode(stopButtonPin, INPUT_PULLUP);
}
 
void loop() {
  switch(timerState) {
    case IDLE:
      // In the IDLE state, display "Press Start" on row 0.
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Press Start");
      lcd.setCursor(0, 1);
      lcd.print("                "); // Clear row 1.
      
      // Wait for the start button press.
      if (digitalRead(startButtonPin) == LOW) {
        delay(50);  // Debounce delay.
        while (digitalRead(startButtonPin) == LOW) {
          delay(10);  // Wait for button release.
        }
        // Start the timer.
        startTime = millis();
        elapsedTime = 0;
        timerState = RUNNING;
        lcd.clear();
      }
      break;
 
    case RUNNING:
      // Update the elapsed time continuously.
      elapsedTime = millis() - startTime;
      displayTime(elapsedTime);
      
      // If the stop button is pressed, pause the timer.
      if (digitalRead(stopButtonPin) == LOW) {
        delay(50);  // Debounce delay.
        while (digitalRead(stopButtonPin) == LOW) {
          delay(10);  // Wait for button release.
        }
        // Capture the elapsed time and change state to PAUSED.
        elapsedTime = millis() - startTime;
        timerState = PAUSED;
      }
      break;
 
    case PAUSED:
      // Display the paused time.
      displayTime(elapsedTime);
      
      // Check for resume or reset:
      // - Start button resumes the timer.
      // - Stop button resets the timer.
      if (digitalRead(startButtonPin) == LOW) {
        delay(50);
        while (digitalRead(startButtonPin) == LOW) {
          delay(10);
        }
        // Resume the timer by adjusting startTime.
        startTime = millis() - elapsedTime;
        timerState = RUNNING;
        lcd.clear();
      }
      else if (digitalRead(stopButtonPin) == LOW) {
        delay(50);
        while (digitalRead(stopButtonPin) == LOW) {
          delay(10);
        }
        // Reset the timer (return to IDLE).
        timerState = IDLE;
        lcd.clear();
      }
      break;
  }
}
 
// Helper function to format and display the elapsed time on row 0.
void displayTime(unsigned long timeInMillis) {
  // Calculate minutes, seconds, and milliseconds.
  unsigned int minutes = timeInMillis / 60000;
  unsigned int seconds = (timeInMillis % 60000) / 1000;
  unsigned int milliseconds = timeInMillis % 1000;
  
  // Create a formatted string "MM:SS:MMM" (always 9 characters).
  char timeStr[10];  // 9 characters + null terminator.
  sprintf(timeStr, "%02u:%02u:%03u", minutes, seconds, milliseconds);
  
  // Display the formatted time on the first row.
  lcd.setCursor(0, 0);
  lcd.print(timeStr);
  
  // Optional: output the time to the Serial Monitor.
  Serial.println(timeStr);
}

Copy the above code to the Arduino IDE editor window. Select the ESP32 board and the COM port. Click on upload button to upload the code.



Working of ESP32 StopWatch Timer

This code implements a basic stopwatch using an ESP32 Microcontroller connected to a standard I2C LCD. It defines three states—IDLE, RUNNING, and STOPPED—using an enumerated type to manage the stopwatch’s behavior. Two buttons are used for user interaction: one to start the timer and one to stop (and later reset) it.

Stopwatch Timer ESP32 initialization

In the IDLE state, the display shows the message “Press Start” and waits for the start button to be pressed.

When the button is activated (with a debounce delay to ensure stable input), the program clears the display, records the current time using the millis() function, and transitions to the RUNNING state. In this state, the stopwatch continuously calculates the elapsed time by subtracting the recorded start time from the current time, formatting this elapsed time into minutes, seconds, and milliseconds, and then displaying it on the LCD.

While in the RUNNING state, if the stop button is pressed, the program again debounces the input, calculates the final elapsed time, and then transitions to the STOPPED state. If start button is pressed here, the timer resumes from the previous value.

Stopwatch using ESP32

In the STOPPED state, the final time remains displayed on the LCD. If the stop button is pressed once more in this state, the code resets the system back to the IDLE state by clearing the display and showing the “Press Start” message again, readying the stopwatch for another timing session.

This is how you can make a stopwatch using ESP32 and 16×2 I2C LCD Display.

Share. Facebook Twitter Pinterest LinkedIn Tumblr Email Reddit Telegram WhatsApp
Previous ArticleInterface BMI160 with Raspberry Pi Pico & MicroPython
Next Article LD2410 Sensor with ESP32 – Human Presence Detection

Related Posts

ESP32 Fingerprint Attendance System with Live Web Dashboard

ESP32 Fingerprint Attendance System with Live Web Dashboard

Updated:June 21, 2026
IoT Based PM & Air Quality Monitoring System using ESP32

IoT Based PM & Air Quality Monitoring System using ESP32

Updated:June 14, 2026
DIY ESP32 MLX90640 IR Thermal Camera with Live Web Display

DIY ESP32 MLX90640 IR Thermal Camera with Live Web Display

Updated:May 10, 20262K
IoT Activity Tracker with ESP32 & Accelerometer Gyroscope

IoT Activity Tracker with ESP32 & Accelerometer/Gyroscope

Updated:May 2, 2026

ESP32 IoT Vehicle Motion Analyzer with MPU6050 & LIS3MDL

Updated:April 27, 20261K
High-Accuracy Pitch, Roll, Yaw with ESP32 & BNO08x IMU

High-Accuracy Pitch, Roll, Yaw with ESP32 & BNO08x IMU

Updated:April 27, 20262K
Add A Comment

CommentsCancel reply

Latest Posts
ESP32 Fingerprint Attendance System with Live Web Dashboard

ESP32 Fingerprint Attendance System with Live Web Dashboard

June 21, 2026
IoT Based PM & Air Quality Monitoring System using ESP32

IoT Based PM & Air Quality Monitoring System using ESP32

June 14, 2026
DIY ESP32 MLX90640 IR Thermal Camera with Live Web Display

DIY ESP32 MLX90640 IR Thermal Camera with Live Web Display

May 10, 2026
IoT Activity Tracker with ESP32 & Accelerometer Gyroscope

IoT Activity Tracker with ESP32 & Accelerometer/Gyroscope

May 2, 2026
A Guide to Sourcing Obsolete ICs for Vintage Projects

Beyond AliExpress: A Guide to Sourcing Obsolete ICs for Vintage Projects

April 21, 2026

ESP32 IoT Vehicle Motion Analyzer with MPU6050 & LIS3MDL

April 27, 2026
Building a Smart Sensor Node with a BLE Microcontroller

Building a Smart Sensor Node with a BLE Microcontroller

February 26, 2026
High-Accuracy Pitch, Roll, Yaw with ESP32 & BNO08x IMU

High-Accuracy Pitch, Roll, Yaw with ESP32 & BNO08x IMU

April 27, 2026
Top Posts & Pages
  • 12V DC to 220V AC Inverter Circuit & PCB
    12V DC to 220V AC Inverter Circuit & PCB
  • ESP32 Fingerprint Attendance System with Live Web Dashboard
    ESP32 Fingerprint Attendance System with Live Web Dashboard
  • ESP32 CAN Bus Tutorial | Interfacing MCP2515 CAN Module with ESP32
    ESP32 CAN Bus Tutorial | Interfacing MCP2515 CAN Module with ESP32
  • Buck Converter: Basics, Working, Design & Application
    Buck Converter: Basics, Working, Design & Application
  • IoT AC Energy Meter with PZEM-004T & ESP32 WebServer
    IoT AC Energy Meter with PZEM-004T & ESP32 WebServer
  • Designing of MPPT Solar Charge Controller using Arduino
    Designing of MPPT Solar Charge Controller using Arduino
  • How to use INA219 DC Current Sensor Module with Arduino
    How to use INA219 DC Current Sensor Module with Arduino
  • LD2410 Sensor with ESP32 - Human Presence Detection
    LD2410 Sensor with ESP32 - Human Presence Detection
Categories
  • Arduino Projects (197)
  • Articles (60)
    • Learn Electronics (19)
    • Product Review (15)
    • Tech Articles (28)
  • Electronics Circuits (46)
    • 555 Timer Projects (21)
    • Op-Amp Circuits (7)
    • Power Electronics (13)
  • IoT Projects (205)
    • ESP32 MicroPython (7)
    • ESP32 Projects (82)
    • ESP32-CAM Projects (15)
    • ESP8266 Projects (76)
    • LoRa/LoRaWAN Projects (22)
  • Microcontrollers (38)
    • AMB82-Mini IoT AI Camera (4)
    • BLE Projects (18)
    • STM32 Projects (19)
  • Raspberry Pi (93)
    • Raspberry Pi Pico Projects (57)
    • Raspberry Pi Pico W Projects (12)
    • Raspberry Pi Projects (24)
Follow Us
  • Facebook
  • Twitter
  • Pinterest
  • Instagram
  • YouTube
About Us

“‘How to Electronics’ is a vibrant community for electronics enthusiasts and professionals. We deliver latest insights in areas such as Embedded Systems, Power Electronics, AI, IoT, and Robotics. Our goal is to stimulate innovation and provide practical solutions for students, organizations, and industries. Join us to transform learning into a joyful journey of discovery and innovation.

Copyright © How To Electronics. All rights reserved.
  • About Us
  • Disclaimer
  • Privacy Policy
  • Contact Us
  • Advertise With Us

Type above and press Enter to search. Press Esc to cancel.

Ad Blocker Enabled!
Ad Blocker Enabled!
Looks like you're using an ad blocker. Please allow ads on our site. We rely on advertising to help fund our site.