Home · Academy · Robotics & Coding · Arduino · Digital Input and Output

Digital Input and Output

Learn to control an LED with a button using digitalRead and digitalWrite.

LESSON COMPASS

What will you use this page for?

Core idea

Digital output lets us control a part such as an LED by turning a pin on and off, and digital input lets us read whether a button is pressed; combining these two ideas lets the Arduino make decisions like "turn on the light when the button is pressed."

Evidence to produce

Complete the page task with your own input, test conditions and reasoning.

Control trap

Forgetting the pinMode line If you do not set the pin type, input and output will not behave as expected. Set the button to INPUT_PULLUP and the LED to OUTPUT inside setup . Connecting an LED without a resistor If you plug the LED directly into a pin, too much current flows. The LED can burn out or the pin can be…

Next connection

Analog Read: A pin can read not just on/off but many values in between. With analogRead we will read a potentiometer or a light sensor and turn it into numbers from 0 to 1023.

Module sources: Python Tutorial · Arduino Learn

LevelBeginner
Age10–16
Duration30–45 min
PrerequisiteFirst Code: Blink
ContentStandard lesson · 1,701 words
Last updated

One-sentence summary

Digital output lets us control a part such as an LED by turning a pin on and off, and digital input lets us read whether a button is pressed; combining these two ideas lets the Arduino make decisions like "turn on the light when the button is pressed."

Why does it matter?

In the Blink lesson we turned an LED on and off. But that LED did not hear anything from us; it just blinked for the time we wrote in the code. Real devices listen to their surroundings: you press a button and a light turns on; you touch a key and a door opens.

In this lesson we meet the two directions of an Arduino. Digital output is the Arduino sending something to the world: it turns a pin on (5 volts) or off (0 volts). Digital input is the Arduino listening to the world: it checks whether there is a signal on a pin.

The word "digital" here simply means there are only two values: on or off, 1 or 0. There is nothing in between. For a button this fits perfectly; a button is either pressed or it is not. This two-value logic is the foundation of every computer.

Digital output: controlling a pin

You may remember from the Blink lesson that the digitalWrite command sets a pin to HIGH (about 5 volts, on) or LOW (0 volts, off). When we connect an LED to that pin through a resistor, the LED lights up when the pin turns on.

Wiring

The resistor is essential. Without it, too much current flows through the LED and the LED (and sometimes the pin) can be damaged. Think of the resistor as a narrowing in a water pipe: it keeps the flow at a safe level.

The code

int ledPin = 8;

void setup() {
  pinMode(ledPin, OUTPUT); // pin 8 will be an output
}

void loop() {
  digitalWrite(ledPin, HIGH); // turn the LED on
  delay(1000);
  digitalWrite(ledPin, LOW);  // turn the LED off
  delay(1000);
}

This is the same as Blink, except we stored the pin number in a variable. The line pinMode(ledPin, OUTPUT) tells the Arduino "I will send a signal out of this pin." If we forget to set a pin as an output, digitalWrite will not work properly.

Digital input: reading a button

Now we want the Arduino to listen. We read the state of a button with the digitalRead command. This command returns HIGH or LOW.

Why do we need INPUT_PULLUP?

When you leave a button pin unconnected, a strange problem appears: the pin is neither on nor off, it picks up electrical noise from the air and reads a random HIGH or LOW. This is called a "floating input."

The fix is to pull the pin to a fixed value with a resistor. The Arduino can do this for us internally: when we write pinMode(pin, INPUT_PULLUP), the pin is pulled to HIGH through a built-in resistor. So when the button is not pressed, digitalRead reads HIGH.

We connect the other leg of the button to GND. When you press the button, the pin is connected to GND and reads LOW. This can feel backwards: pressed = LOW, released = HIGH. But not needing an external resistor makes it worth it.

Wiring

Watching the button with Serial

First let us see what the button reads with our own eyes. Serial lets us send messages from the Arduino to the computer.

int buttonPin = 2;

void setup() {
  Serial.begin(9600);
  pinMode(buttonPin, INPUT_PULLUP);
}

void loop() {
  int state = digitalRead(buttonPin);
  Serial.println(state); // pressed=0, released=1
  delay(200);
}

When you upload the code and open the Serial Monitor, you see 1 (HIGH) when the button is not pressed and 0 (LOW) when you press it. This is how we read the invisible language of electricity.

Combine the two: control an LED with a button

Now for the real goal: the LED lights up when the button is pressed and turns off when you release it. We combine input and output in one program.

int buttonPin = 2;
int ledPin = 8;

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
}

void loop() {
  if (digitalRead(buttonPin) == LOW) { // pressed
    digitalWrite(ledPin, HIGH);        // turn LED on
  } else {
    digitalWrite(ledPin, LOW);         // turn LED off
  }
}

The program keeps looping inside loop. On every turn it reads the button. If it is pressed (LOW) it turns the LED on, otherwise it turns it off. This is the condition structure from the Algorithms lesson, now working on real hardware: "If the button is pressed, turn on the light."

Two everyday examples

A doorbell. A bell button works with exactly this logic. When you press it the circuit closes and the sound inside turns on; when you release it, it goes quiet. Our button-and-LED is a tiny doorbell; it just gives light instead of sound.

A fridge light. When you open the door the light turns on, when you close it the light turns off. A small switch at the edge of the door feeds a digital input. While the door is closed the switch is pressed (light off); when it opens the switch is released (light on). It is the same "read the input, decide the output" idea.

Mini practice

Build and run the button-and-LED circuit above. Then change the code so that each press of the button toggles the LED (if it is on, turn it off; if it is off, turn it on) — just like a real room light switch.

Hint: Keep the LED's state in a variable. To catch the moment the button is pressed, also store the previous reading.

int buttonPin = 2;
int ledPin = 8;
bool ledOn = false;
int previousState = HIGH;

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
}

void loop() {
  int state = digitalRead(buttonPin);
  if (previousState == HIGH && state == LOW) { // new press
    ledOn = !ledOn;
    digitalWrite(ledPin, ledOn);
    delay(50); // reduce bounce
  }
  previousState = state;
}

Run it and observe: sometimes a single press seems to toggle twice. We explain why in the "Common mistakes" section.

Common mistakes

Forgetting the pinMode line

If you do not set the pin type, input and output will not behave as expected. Set the button to INPUT_PULLUP and the LED to OUTPUT inside setup.

Connecting an LED without a resistor

If you plug the LED directly into a pin, too much current flows. The LED can burn out or the pin can be damaged. Always connect it through a 220–330 ohm resistor.

Getting the INPUT_PULLUP logic backwards

With INPUT_PULLUP a button reads HIGH when released and LOW when pressed. If you write == HIGH instead of == LOW, the LED behaves the opposite way.

Button bounce (debounce)

Buttons work with metal contacts; the moment you press, the contact jitters for a few milliseconds. The Arduino may read this as several presses. A small delay(50), or a wait built with millis, smooths out this bounce.

Safety note

Lesson summary

Check questions

  1. What does the command digitalWrite(8, HIGH) do?
  2. Which command do we use to read the state of a button?
  3. With INPUT_PULLUP, what does digitalRead return when the button is released: HIGH or LOW?
  4. What can happen if we connect an LED without a resistor?
  5. To turn the LED on when the button is pressed, how do we write the if condition as digitalRead(buttonPin) == ? (with INPUT_PULLUP)?

Answers

  1. It sets pin 8 to HIGH (about 5 volts); if an LED is connected to that pin through a resistor, it lights up.
  2. We use the digitalRead command; it returns HIGH or LOW.
  3. It returns HIGH. INPUT_PULLUP pulls the pin to HIGH through a built-in resistor; when the button is pressed the pin connects to GND and becomes LOW.
  4. Too much current flows through the LED; the LED can burn out or the Arduino pin can be damaged. This is why we use a 220–330 ohm resistor.
  5. We write if (digitalRead(buttonPin) == LOW). Because with INPUT_PULLUP a pressed button reads LOW.

Source and verification note

For “Digital Input and Output”, verification focuses on whether the relationship between Digital output: controlling a pin and The code remains consistent across examples. Pin, voltage and current limits can differ between Arduino-compatible boards. Compiling code does not guarantee a safe circuit; loads such as motors and servos require a suitable driver and external power where appropriate.

Next lesson

Analog Read: A pin can read not just on/off but many values in between. With analogRead we will read a potentiometer or a light sensor and turn it into numbers from 0 to 1023.

Start QuizBack to Arduino
QUESTION POOL

Reinforce this lesson with 10 questions

This lesson has a pool of 20 questions. Each attempt selects 10 and reshuffles the choices.