Digital I/O

Lesson 13 - Understanding Digital Input in Arduino

Learn how Arduino reads button and switch signals using digital inputs, pinMode(), and digitalRead() in beginner-friendly examples.

Progress indicator

Lesson 13 of 13

Learning Objectives

  • Understand what digital input means in Arduino and ESP32 projects.
  • Use pinMode() to configure a pin as INPUT or INPUT_PULLUP.
  • Read a button state using digitalRead() and understand HIGH/LOW values.
  • Learn beginner debouncing basics to reduce noisy button readings.
  • Avoid common mistakes when wiring and reading digital inputs.
  • Recognize active-low behavior in common INPUT_PULLUP button circuits.

Concept Explanation

What is Digital Input

A digital input reads a pin as one of two states: HIGH or LOW. This is commonly used for buttons, switches, and simple on/off sensors.

In beginner projects, digital input is often the first step to making a program react to user actions.

A digital input does not measure a full analog range. It only answers a simple yes/no style question: “Is this signal HIGH or LOW right now?”

Digital Input Syntax

Digital input usually involves three steps:

pinMode(buttonPin, INPUT_PULLUP);
int state = digitalRead(buttonPin);
if (state == LOW) { /* pressed */ }

The pin setup happens once in setup(), and the reading usually happens repeatedly in loop().

pinMode() for Input

Use pinMode(pin, INPUT) or pinMode(pin, INPUT_PULLUP) to configure a pin for reading a signal.

If a pin is not configured correctly, digitalRead() may return unreliable values.

Always think of pinMode() as telling the microcontroller what role the pin should play before you use it.

INPUT vs INPUT_PULLUP

INPUT reads an external signal directly and usually needs an external resistor for stable readings.

INPUT_PULLUP uses an internal pull-up resistor, which is very common for beginner button circuits.

With INPUT_PULLUP, the pin is normally held HIGH until the button connects it to GND (which makes it LOW).

digitalRead() Basics

digitalRead(pin) returns either HIGH or LOW based on the current signal level on the pin.

You usually store this result in a variable first, then check it with if conditions.

Reading Button State

A button is usually read by calling digitalRead(buttonPin) and storing the result in a variable like buttonState.

Your code then checks if the button is pressed or released and reacts (for example, turning on an LED).

Beginner reading pattern

1) Read the button into buttonState, 2) compare with HIGH or LOW, 3) run the action.

HIGH vs LOW Meaning

HIGH means the pin is reading a high voltage logic level. LOW means the pin is reading a low voltage logic level.

With INPUT_PULLUP, many button circuits read LOW when pressed and HIGH when released (the logic looks reversed at first, but this is normal).

Active-high logic

Pressed = HIGH (common with some external resistor circuits).

Active-low logic

Pressed = LOW (very common with INPUT_PULLUP).

Debouncing Basics

Real buttons can bounce (rapidly switch between HIGH/LOW briefly) when pressed or released. A simple beginner approach is adding a short delay (for example, delay(20) to delay(50)) after reading or handling a press.

This is not the most advanced method, but it is a good first step before learning non-blocking debounce techniques.

When to Use Digital Input

  • Push buttons and switches
  • Limit switches
  • Simple digital sensors (ON/OFF output)
  • User controls that trigger actions in code

Real-Life Example

A lift button, door switch, machine start button, or menu-select button all behave like digital inputs: pressed/released or ON/OFF.

Example Code

This example reads a button using INPUT_PULLUP and turns an LED on when the button is pressed.

const int buttonPin = 0;
const int ledPin = 2;
int buttonState = LOW;

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
  Serial.begin(115200);
}

void loop() {
  buttonState = digitalRead(buttonPin);

  if (buttonState == LOW) {
    digitalWrite(ledPin, HIGH);
    Serial.println("Button pressed");
  } else {
    digitalWrite(ledPin, LOW);
    Serial.println("Button released");
  }

  delay(50); // simple debounce delay
}

What this example teaches

  • How to configure a button pin with INPUT_PULLUP
  • How to read a button state with digitalRead()
  • How to handle active-low button logic
  • How a simple debounce delay reduces noisy reads

Example Code Explanation

  1. buttonPin and ledPin store the pin numbers.
  2. pinMode(buttonPin, INPUT_PULLUP) configures the button pin as a digital input with an internal pull-up resistor.
  3. buttonState = digitalRead(buttonPin) reads the current button signal.
  4. The code checks if (buttonState == LOW) because the button press is active-low when using INPUT_PULLUP.
  5. When pressed, the LED turns on and a Serial message is printed.
  6. When released, the LED turns off and a different Serial message is printed.
  7. delay(50) adds a simple debounce delay to reduce noisy reads.

Beginner reading tip

Focus on 3 parts first: setup (pin modes), read (digitalRead), react (turn LED on/off).

Real-life example

A doorbell button, machine start button, or menu button on a device is a common digital input use case.

Common Mistakes with Digital Input

  • Forgetting to set pinMode() for the input pin.
  • Confusing HIGH/LOW logic when using INPUT_PULLUP.
  • Ignoring button bounce and seeing multiple false triggers.
  • Using floating inputs (unstable readings) with INPUT and no proper resistor setup.
  • Reading the button correctly but forgetting that INPUT_PULLUP often means pressed = LOW.

Best Practices for Digital Input

  • Use INPUT_PULLUP for beginner button circuits when appropriate.
  • Use clear names like buttonPin and buttonState.
  • Document whether your logic is active-high or active-low.
  • Start with simple debounce handling, then learn non-blocking debounce later.
  • Test and print the raw button state in Serial when debugging input logic.

Practice Task

  1. Change the code so the LED toggles only while the button is pressed.
  2. Print the raw buttonState value to Serial for debugging.
  3. Change the debounce delay from 50 to 20 and explain what might happen.
  4. Explain why INPUT_PULLUP often makes button circuits easier for beginners.

Try it now

Open the simulator workspace to practice button input and see how digitalRead() changes LED behavior.

Run in Simulator