Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

Build a simple Arduino Uno event counter that increases by one whenever a physical pushbutton is pressed and shows the current value on a 16×2 character LCD. This version uses the LCD in four-bit mode, Arduino’s internal pull-up resistor, and non-blocking software debouncing so one press produces one count.

The project is suitable for counting classroom demonstrations, completed tasks, manual production steps, or people passing a checkpoint. It is a manual button counter—not an automatic, calibrated, high-speed counter for industrial or safety-critical use.

What you will build

The signal flow is:

button press → digital input transition → debounce → count + 1 → LCD update

The Arduino Uno R3 provides 5 V operation, 14 digital I/O pins, and internal pull-up resistors. A conventional HD44780-compatible 16×2 LCD can be controlled in four-bit mode with Arduino’s official LiquidCrystal library.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Required components

  • Arduino Uno R3 or compatible Uno board
  • HD44780-compatible 16×2 LCD, commonly sold as an LCD1602
  • Momentary normally-open tactile pushbutton
  • 10 kΩ potentiometer for LCD contrast
  • Breadboard and jumper wires
  • USB cable
  • Optional 220 Ω resistor for the backlight if the LCD module does not already include one

A 16×2 LCD is a character display for letters and numbers, not a graphical display. A bare parallel LCD is used in the main circuit below. An LCD1602 with an I²C backpack needs different wiring and initialization.

#1 Best Overall
Hosyond 3pcs I2C IIC 1602 LCD Display Module 16x02 LCD Screen Module for Arduino Raspberry Pi
  • 1602 LCD screen can display 2 lines x 16 characters, with i2c serial interface, blue display.
  • Built-in independent potentiometer, backlight can be adjusted through the back potentiometer.
  • Power supply: 5v; I2C address: 0x27; wiring method: GND—GND, VCC—VCC, SDA—A4, SCL—A5.
  • Compatible with most development boards, such as Arduino, Raspberry pi, Tinkerboard, Nano pi, Banana pi, stm32, etc.
  • Widely used in: Internet of Things, school electronics projects, smart buildings, maker DIY projects, etc., can display letters, characters, numbers, real-time clock or temperature.

Wiring the circuit

Arduino and LCD connections

Function Arduino Uno LCD connection
LCD RS D12 RS
LCD Enable D11 E
LCD D4 D5 D4
LCD D5 D4 D5
LCD D6 D3 D6
LCD D7 D2 D7
LCD power 5V VDD
LCD ground GND VSS
LCD read/write GND R/W

LCD pin-by-pin wiring

LCD pin Connection
1, VSS GND
2, VDD 5V
3, VO Potentiometer wiper
4, RS Arduino D12
5, R/W GND
6, E Arduino D11
11, D4 Arduino D5
12, D5 Arduino D4
13, D6 Arduino D3
14, D7 Arduino D2
15, LED+ 5V through a suitable resistor if required
16, LED− GND

Connect the two outer potentiometer pins to 5V and GND, and connect its middle pin—the wiper—to LCD pin 3, VO. Leaving VO unconnected is a common reason for a backlit LCD to show no visible characters.

Pushbutton wiring

  • Connect one side of the normally-open button to Arduino D7.
  • Connect the opposite side to GND.
  • Do not add an external pull-up resistor for this version.

With INPUT_PULLUP, the logic is inverted:

Button state Arduino reading
Released HIGH
Pressed LOW

Many four-leg tactile switches have two internally connected legs on each side. Insert the switch across the breadboard’s center gap so pressing it connects the two sides. If it is rotated incorrectly, the input may remain permanently connected or never change.

Complete Arduino sketch

#include <LiquidCrystal.h>

const byte BUTTON_PIN = 7;

// LCD pins: RS, E, D4, D5, D6, D7
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

unsigned long count = 0;

bool buttonStableState = HIGH;
bool lastButtonReading = HIGH;
unsigned long lastDebounceTime = 0;

const unsigned long debounceDelay = 30;

void displayCount() {
  lcd.setCursor(0, 0);
  lcd.print("Digital Counter ");

  lcd.setCursor(0, 1);
  lcd.print("Count:          ");  // Remove old digits
  lcd.setCursor(7, 1);
  lcd.print(count);
}

void setup() {
  pinMode(BUTTON_PIN, INPUT_PULLUP);

  lcd.begin(16, 2);
  lcd.clear();
  displayCount();
}

void loop() {
  bool reading = digitalRead(BUTTON_PIN);

  // A raw change starts or restarts the debounce timer.
  if (reading != lastButtonReading) {
    lastDebounceTime = millis();
  }

  // Accept the new state only after it remains unchanged.
  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (reading != buttonStableState) {
      buttonStableState = reading;

      // Count once when the stable state becomes pressed.
      if (buttonStableState == LOW) {
        count++;
        displayCount();
      }
    }
  }

  lastButtonReading = reading;
}

How the code works

pinMode(BUTTON_PIN, INPUT_PULLUP) enables the Uno’s internal pull-up resistor, which keeps the input from floating when the button is released. The button then pulls D7 to ground when pressed, so the pressed condition is LOW.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Do not use this test with the stated wiring:

if (digitalRead(BUTTON_PIN) == HIGH) {
  count++;
}

That would interpret the released state as a press.

Rank #2
Hosyond 3pcs IIC I2C 2004 LCD Module 20x04 LCD Screen Module Display for Arduino Raspberry Pi
  • 2004 LCD screen can display 4 lines x 20 characters, with i2c serial interface, blue display.
  • Compatible with most development boards, such as Arduino, Raspberry pi, Tinkerboard, Nano pi, Banana pi, stm32, etc.
  • Power supply: 5v; I2C address: 0x27; wiring method: GND—GND, VCC—VCC, SDA—A4, SCL—A5.
  • Built-in independent potentiometer, backlight can be adjusted through the back potentiometer.
  • Widely used in: Internet of Things, school electronics projects, smart buildings, maker DIY projects, etc., can display letters, characters, numbers, real-time clock or temperature.

Mechanical contacts can bounce briefly between open and closed. The sketch waits until the raw reading has stayed unchanged for approximately 30 milliseconds before accepting it. A 20–50 ms interval works for many tactile buttons, but the ideal value depends on the switch and electrical environment. The millis()-based method does not block the rest of the program with delay(), making it easier to add more controls later.

The LCD is refreshed only when the count changes. The blank spaces after Count: erase old digits, so a value such as 100 does not leave a stale digit behind when the display later shows 101 or a shorter value.

Upload and test the project

  1. Install the current Arduino IDE or use the Arduino Cloud Editor.
  2. Connect the Uno to the computer by USB.
  3. Open a new sketch and paste the complete code.
  4. Select Tools → Board → Arduino AVR Boards → Arduino Uno.
  5. Select the correct serial port under Tools → Port.
  6. Click Verify, then click Upload.
  7. Turn the contrast potentiometer slowly until the characters become visible.
  8. Press and release the button repeatedly. The display should increase once per press.

The count initially displays as zero. Holding the button down does not continuously increment it; releasing and pressing again produces the next count.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What happens after reset or power loss?

The example stores count in RAM. It returns to zero after a reset, USB disconnect, or power loss. The unsigned long type commonly provides a range from 0 to 4,294,967,295 on the classic Uno’s 8-bit architecture, but type sizes depend on the Arduino-compatible board and its C++ implementation. A long-running design should define what happens at rollover rather than assuming unlimited counting.

Rank #3
Hosyond 4.0 Inches 480x320 TFT Touch Screen LCD Display Module SPI ST7796S Driver for Arduino R3/Mega2560
  • 4.0-inch color screen,support 65K color display,display rich colors, 480X320 resolution, with touch function.
  • Using the SPI serial bus, it only takes a few IOs to illuminate the display.
  • Eeasy to expand the experiment with SD card slot and touch pen.
  • Compatible with Arduino R3/Nano/Mega controller boards, which will improve your project operation.
  • Provide a rich sample program and underlying driver technical support.

Saving the count with EEPROM

The Uno’s EEPROM can preserve a value through power loss, but it has a limited write lifetime. Never write the count on every pass through loop(). Write only when the count changes, periodically, or when a deliberate save action occurs. For counters that receive many presses, consider wear-leveling or external nonvolatile storage instead of repeatedly updating one EEPROM address.

Adding reset or decrement controls

You can add a second debounced button—for example, a reset button on D8—or a decrement button. The new button should use the same INPUT_PULLUP wiring and transition-based debounce logic as the increment button.

For decrementing, prevent unsigned underflow:

if (count > 0) {
  count--;
}

Decide what “reset” means for your project: an immediate zero button, a long press, a second confirmation button, or a value cleared only after a power cycle. A reset input must also be debounced.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Parallel LCD versus I²C LCD

Parallel LCD

The baseline circuit uses six signal connections:

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

Its advantages are the official library, transparent wiring, and a useful introduction to LCD protocols. Its disadvantages are more wires and six occupied digital pins.

Rank #4
LCD 2004 I2C (TWI) 20x4 Display Module with Blue Backlight, Adjustable Contrast, Compatible with Arduino Uno R3 R4, ESP32, ESP8266, Raspberry Pi, Tutorials Included
  • LARGE I2C 20X4 CHARACTER DISPLAY MODULE – This I2C (TWI) 20x4 display shows up to 80 characters across four rows, making it perfect for displaying sensor data, logs, menus, or debug info in DIY electronics and Arduino projects.
  • BLUE BACKLIGHT DISPLAY WITH ADJUSTABLE CONTRAST – Features a vibrant blue backlight LCD and onboard potentiometer to fine-tune contrast, ensuring excellent readability in low or bright lighting—ideal for both indoor and outdoor Arduino Uno R3 or ESP32 projects.
  • I2C (TWI) COMMUNICATION TO SAVE PINS – Uses the I2C protocol (also known as TWI or Two-Wire Interface), which reduces the number of connections to just two signal wires—great for compact microcontroller setups using ESP8266, Raspberry Pi, and more.
  • FULLY COMPATIBLE WITH ARDUINO UNO R3 / R4, ESP32, ESP8266, RASPBERRY PI – Works seamlessly with Arduino Uno R3, the latest Arduino Uno R4, Raspberry Pi boards, and MicroPython-based controllers. Ideal for makers, students, and engineers.
  • ONLINE TUTORIALS INCLUDED – Easy-to-follow online guides walk you through setup, code examples, and integration with Arduino, ESP32, ESP8266, and Raspberry Pi. Just search: DIYables LCD 2004 I2C Display.

I²C LCD

An LCD1602 fitted with a PCF8574-style I²C backpack generally needs 5V, GND, SDA, and SCL. On an Uno R3, SDA and SCL are available through the board’s I²C/TWI interface. This saves GPIO pins and makes the breadboard neater.

However, I²C backpacks vary. Common addresses such as 0x27 and 0x3F are not universal, and different backpacks can use different pin mappings. You need a compatible I²C LCD library and may need an address-scanner sketch. An I²C module is not a drop-in replacement for the parallel code: the library, initialization, and wiring are different.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshooting

The backlight is on but no characters appear

  1. Confirm LCD pin 1 is connected to GND and pin 2 to 5V.
  2. Confirm pin 3, VO, is connected to the potentiometer wiper.
  3. Connect the potentiometer’s outer pins to 5V and GND, then turn it across its full range.
  4. Verify that R/W is connected to GND.
  5. Check every signal wire against LiquidCrystal lcd(12, 11, 5, 4, 3, 2).

Random blocks or corrupted characters appear

Check for loose breadboard connections, a missing common ground, incorrect D4–D7 order, long signal wires, incorrect supply voltage, an ungrounded R/W pin, or a damaged or incompatible LCD module.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

One press adds several counts

Check that the supplied debounce code is present, the button is wired between D7 and GND, and the pin is configured as INPUT_PULLUP. A debounce interval that is too short, long wires, or electrical noise can also cause multiple transitions.

Best Value
SunFounder IIC/I2C/TWI LCD1602 Display Module Compatible with Arduino and Raspberry Pi
  • Easy to use. Less I/O ports are occupied, only four - VCC, GND, SDA (serial data line), SCL (serial clock line).
  • Support IIC protocol. The I2C LCD1602 library is provided, so you can call it directly.
  • With a potentiometer used to adjust backlight and contrast.
  • Power supply: +5V; Address of the module: ox27
  • Note: This item is suitable for 14 years and older.

The count increases at startup

If the button is physically held down during startup, the first stable LOW state is correctly interpreted as a press. If that is undesirable, require the button to be released before enabling counting, or initialize the stable state from the startup reading.

The sketch will not compile

Confirm that the board and port are selected, the code was copied completely, and LiquidCrystal is spelled and capitalized correctly. It is normally available in the Arduino environment and is listed in Arduino’s official library documentation.

Project limitations and useful upgrades

Design choice Simple approach More robust approach
Button input INPUT_PULLUP External filtering or hardware conditioning
Debounce Short delay() Non-blocking millis() debounce
Display Parallel LCD I²C LCD backpack
Storage RAM EEPROM or external nonvolatile memory
Reset Power cycle Dedicated debounced button
Event source Human button Sensor with suitable signal conditioning

This project is a good foundation for a score display, task counter, queue token demonstrator, or manual checkpoint counter. If you need automatic object detection, use an appropriate optical, infrared, ultrasonic, magnetic, or other sensor instead of treating a human pushbutton as a production counting device. High-speed or safety-critical applications require electrical protection, signal conditioning, testing, and a deliberately specified rollover and fault-handling policy.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Quick Recap

Bestseller No. 3
Hosyond 4.0 Inches 480x320 TFT Touch Screen LCD Display Module SPI ST7796S Driver for Arduino R3/Mega2560
Hosyond 4.0 Inches 480x320 TFT Touch Screen LCD Display Module SPI ST7796S Driver for Arduino R3/Mega2560
Using the SPI serial bus, it only takes a few IOs to illuminate the display.; Eeasy to expand the experiment with SD card slot and touch pen.
$19.99
Bestseller No. 5
SunFounder IIC/I2C/TWI LCD1602 Display Module Compatible with Arduino and Raspberry Pi
SunFounder IIC/I2C/TWI LCD1602 Display Module Compatible with Arduino and Raspberry Pi
Support IIC protocol. The I2C LCD1602 library is provided, so you can call it directly.; With a potentiometer used to adjust backlight and contrast.
$9.99

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.