Push Buttons in Digital Circuits

a person pressing a lift button

Connecting Push Buttons to Digital Circuits and Arduino

Introduction

Push buttons are among the most essential and widely used components in electronics. Whether it’s starting a program, toggling a device, or navigating a menu, push buttons allow human interaction with digital circuits. In this article, we’ll walk you through how to connect push buttons to microcontrollers like Arduino, explain pull-up/down resistors, explore switch debouncing, and provide a practical example with clean, structured Arduino code.

a collection of push buttons

What Is a Push Button?

A push button is a mechanical switch that temporarily completes or breaks an electrical connection when pressed. Typically, they are normally open (NO), meaning the circuit is open until the button is pressed.

When used with microcontrollers, buttons are connected to input pins that detect voltage levels — either HIGH (1) or LOW (0) — based on how the button is wired.

momentary push button switch
Push button internal details

Pull-Up vs Pull-Down Resistors

A digital input pin must be connected to a known voltage when idle. If left floating (disconnected), it may randomly read HIGH or LOW due to electrical noise. Pull-up and pull-down resistors ensure the input pin has a stable logic level when the button is not pressed.

Pull-Down Configuration

  • Wiring: One side of the button to 5V, the other to the input pin, with a resistor to GND.
  • Behavior:
    • Button not pressed: pin reads LOW.
    • Button pressed: pin reads HIGH.
Pull dow resistor connected to MCU

Pull-Up Configuration

  • Wiring: One side of the button to GND, the other to the input pin, with a resistor to 5V.
  • Behavior:
    • Button not pressed: pin reads HIGH.
    • Button pressed: pin reads LOW.

This is the preferred method for Arduino projects because Arduino has internal pull-up resistors.

Pull up resistor connected to MCU

Using Internal Pull-Up Resistors in Arduino

Arduino simplifies pull-up configuration by allowing you to enable an internal pull-up resistor via code:

1pinMode(buttonPin, INPUT_PULLUP);

This removes the need for an external resistor. In this configuration, the button is connected between the input pin and GND.

Choosing the Right Resistor Value

If using external resistors:

  • Typical value: 10kΩ
  • Lower than 4.7kΩ: wastes current.
  • Higher than 50kΩ: might result in weak logic levels.

10kΩ is a common and reliable choice.

Internal pull up resisitor

What Is Switch Debouncing?

When a button is pressed or released, its contacts mechanically bounce for a few milliseconds. This bounce causes the input signal to rapidly fluctuate, which digital systems might interpret as multiple presses.

Bouncing signal due to push button click

How to Handle Debouncing

To avoid false or repeated triggering from a single press, debouncing techniques are used.

Option 1: Hardware Debouncing

A basic RC (Resistor-Capacitor) circuit can be added to filter out the bouncing. This smooths the voltage change at the input pin.

Example Circuit:

  • Place a 10kΩ resistor between the button and the digital input pin.
  • Connect a 100nF capacitor from the input pin to GND.

This setup absorbs the fast voltage fluctuations caused by bouncing, ensuring that the pin voltage rises and falls smoothly.

Hardware debounce is simple and effective, especially when microcontroller resources are limited.

pull-down-resistor-with-debounce-capacitor
de-bouncing-button-with-capacitor-graph

Option 2: Software Debouncing

This method uses a short time delay in the code to filter out bouncing effects. It’s more flexible and doesn’t require extra components.

The microcontroller waits for a fixed period (e.g., 50 milliseconds) after detecting a change in button state before considering the change valid.


Example: Button Counter with Reset — Using Structured Code

This practical example uses two push buttons connected to an Arduino:


  • Button A (on pin 2): Increments a counter.
  • Button B (on pin 3): Resets the counter to 0.

We’ll explain both the circuit wiring and the code logic.

Circuit Description

Each push button is connected using the internal pull-up resistor configuration.

Wiring Details:

  • Button A:
    • One leg connected to Arduino digital pin 2
    • Other leg connected to GND
  • Button B:
    • One leg connected to Arduino digital pin 3
    • Other leg connected to GND

Since we use INPUT_PULLUP in code, the default logic is:

  • Not pressed → HIGH (pulled up by resistor)
  • Pressed → LOW (shorted to GND)

This is completely safe and common practice in Arduino digital input design.

Arduino Code (with Explanation Below)

1const int buttonA = 2;
2const int buttonB = 3;
3
4const unsigned long debounceDelay = 50;
5int counter = 0;
6
7// Structure to track each button's state and debounce timing
8struct Button {
9 int pin;
10 int lastState;
11 unsigned long lastDebounceTime;
12};
13
14Button btnA = {buttonA, HIGH, 0};
15Button btnB = {buttonB, HIGH, 0};
16
17void setup() {
18 pinMode(btnA.pin, INPUT_PULLUP);
19 pinMode(btnB.pin, INPUT_PULLUP);
20 Serial.begin(9600);
21}
22
23bool debounce(Button &btn) {
24 int reading = digitalRead(btn.pin);
25 bool pressed = false;
26
27 if (reading != btn.lastState) {
28 btn.lastDebounceTime = millis(); // Reset debounce timer
29 }
30
31 if ((millis() - btn.lastDebounceTime) > debounceDelay) {
32 // Check for falling edge (HIGH to LOW)
33 if (reading == LOW && btn.lastState == HIGH) {
34 pressed = true;
35 }
36 }
37
38 btn.lastState = reading;
39 return pressed;
40}
41
42void loop() {
43 if (debounce(btnA)) {
44 counter++;
45 Serial.print("Count: ");
46 Serial.println(counter);
47 }
48
49 if (debounce(btnB)) {
50 counter = 0;
51 Serial.println("Counter Reset");
52 }
53}
54
arduino board connected to 2 switches

Code Explanation

  • Struct Button: Groups each button’s pinlastState, and debounce timing.
  • Function debounce():
    • Detects changes in state.
    • Waits 50 ms to see if state is stable (no bouncing).
    • Only returns true if the button was just pressed (a falling edge).
  • In loop():
    • If Button A is pressed, counter is incremented and displayed.
    • If Button B is pressed, counter is reset and a message is printed.

Output in Serial Monitor

When viewed in the Arduino Serial Monitor, the result looks like:


1Count: 1
2Count: 2
3Count: 3
4Counter Reset
5Count: 1
6...
7

Each press is counted once, even if your finger bounces. The reset button clears the counter immediately.

Summary

  • Push buttons are simple but powerful components in digital systems.
  • Always use pull-up or pull-down resistors to avoid floating input pins.
  • Arduino’s INPUT_PULLUP makes wiring easy by using internal resistors.
  • Debouncing is essential to avoid false signals from mechanical bounce.
  • Hardware debounce uses an RC filter to smooth input.
  • Software debounce uses timing logic to detect valid presses.
  • Structured code helps keep multi-button logic clean and maintainable.

Or you can explore other categories

Arduino robot and rover

Electronics

A DIY made aircraft rc model with a transmitter

RC Flight Physics

Children looking into a microscop in turns

Microscopy