Interactive Mission

Button Controls LED with ESP32

Make your ESP32 react to your hand. In this mission a push button becomes an input, an LED becomes the output, and your code connects cause to effect.

Mission 02FoundationBeginner15-20 minutesParent SafeTeacher Friendly
Mission 02

Press a Button, Control a Light

The Story

Your ESP32 can already speak with an LED. Now it needs to listen.

A button is the simplest way for a human to talk to a microcontroller. Pressed means one thing. Released means another. This tiny idea appears everywhere: doorbells, keyboards, machine controls, robot bumpers, reset buttons, and safety switches.

Explain Like I'm 12

A button is like a tiny bridge. When you press it, it connects two points together. The ESP32 watches one pin and asks: is this pin HIGH or LOW right now?

The trick is that an unpressed button must still have a clear value. INPUT_PULLUP gives the pin a gentle built-in connection to 3.3 V, so it reads HIGH until the button pulls it down to GND.

Academy Path

Current mission: Mission 02 Β· Foundation

Expected outcome: Pressing the button turns the LED on. Releasing the button turns it off.

Mini challenge: Change the code so one button press toggles the LED state instead of holding it on.

Required Knowledge

Skills You Unlock

  • Read a digital input with digitalRead()
  • Use INPUT_PULLUP to avoid floating button signals
  • Connect a button safely between GPIO and GND
  • Control an output from an input condition
  • Debug pressed and released states in Serial Monitor
Previous
Next

What You'll Build

  • A push button wired to ESP32 GPIO27.
  • An LED wired to ESP32 GPIO2 through a resistor.
  • Code that reads the button and turns the LED on while the button is pressed.
  • Serial Monitor messages that show PRESSED and RELEASED states.

Things You'll Need

  • ESP32 DevKit boardAny USB-programmable ESP32 board
  • Push buttonStandard 4-leg tactile button
  • LEDAny color
  • 220 ohm resistorProtects the LED from too much current
  • Breadboard and jumper wiresFor the button and LED circuit
  • USB data cableFor upload and Serial Monitor

Component Spotlight

This mission uses the ESP32 DevKit as both a listener and a controller.

Digital Input, Pull-Up, and Floating Pins

Concept Illustration ESP32 GPIO27 connected to a push button that goes to GND, with internal pull-up enabled; GPIO2 drives an LED through a resistor to GND

A digital input has only two useful states: HIGH or LOW. HIGH means the pin is near 3.3 V. LOW means the pin is near GND.

If a button pin is not connected to anything when released, it can float. A floating pin is like an unanswered question: it may randomly read HIGH or LOW because tiny electrical noise is enough to move it.

INPUT_PULLUP fixes that. The ESP32 connects a weak internal resistor from the pin to 3.3 V. When the button is released, the pin reads HIGH. When the button is pressed, the button connects the pin to GND, so it reads LOW.

Breadboard Wiring

Follow these steps in order. Unplug USB before you change any wires.

Wiring Diagram Button one side to ESP32 GPIO27, other side to GND; LED long leg through 220 ohm resistor to GPIO2, LED short leg to GND
  1. 1

    Unplug the ESP32 USB cable before wiring.

  2. 2

    Place the push button across the center gap of the breadboard so its two sides are separated.

  3. 3

    Connect one side of the button to ESP32 GPIO27.

  4. 4

    Connect the opposite side of the button to ESP32 GND.

  5. 5

    Place the LED on the breadboard with the long leg and short leg in separate rows.

  6. 6

    Connect ESP32 GPIO2 to one end of the 220 ohm resistor.

  7. 7

    Connect the other end of the resistor to the LED long leg row.

  8. 8

    Connect the LED short leg row to ESP32 GND.

  9. 9

    Plug USB back in and upload the code.

Code

Copy this into Arduino IDE, then click Upload.

button_controls_led.ino
const int BUTTON_PIN = 27;
const int LED_PIN = 2;

void setup() {
  Serial.begin(115200);
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);
  Serial.println("Button controls LED mission ready");
}

void loop() {
  int buttonReading = digitalRead(BUTTON_PIN);
  bool buttonPressed = (buttonReading == LOW);

  digitalWrite(LED_PIN, buttonPressed ? HIGH : LOW);

  if (buttonPressed) {
    Serial.println("Button: PRESSED | LED: ON");
  } else {
    Serial.println("Button: RELEASED | LED: OFF");
  }

  delay(100);
}
  • INPUT_PULLUP makes the released button read HIGH.
  • Pressing the button connects GPIO27 to GND, so the reading becomes LOW.
  • The code converts that reading into a clear pressed variable.
  • Serial output helps you prove the button is working before trusting the LED.

Expected Serial Monitor Output

Open Serial Monitor at 115200 baud.

When the button is not pressed, you should see: Button: RELEASED | LED: OFF

When you press and hold the button, you should see: Button: PRESSED | LED: ON

The LED should turn on only while the button is pressed.

Mini Quiz

Quick check β€” no grades, just confidence!

Q1. What does INPUT_PULLUP do?

Q2. What does the button read when pressed in this circuit?

Q3. Why should the LED use a resistor?

Challenge Yourself

No wrong answers β€” experiment and have fun!

  • Change the program so each button press toggles the LED on or off.
  • Print only when the button changes state instead of printing every 100 ms.
  • Make the LED stay on for 3 seconds after the button is pressed.
  • Replace the LED with a relay module after reading the relay component guide.

Common Problems

Most ESP32 problems are wiring, power, library, or timing issues. Check these first.

  • Button always reads PRESSED

    Likely cause: The GPIO may be connected to GND all the time, or the button legs are placed in the wrong breadboard rows.

    Fix: Rotate the button 90 degrees or move it across the breadboard center gap. Confirm one side goes to GPIO27 and the opposite side goes to GND.

  • Button changes randomly

    Likely cause: The input is floating because INPUT_PULLUP is missing or the wire is loose.

    Fix: Use pinMode(BUTTON_PIN, INPUT_PULLUP), tighten the jumper wires, and keep the circuit short.

  • LED never turns on

    Likely cause: The LED may be backwards, the resistor may not be in series, or the wire may not be on GPIO2.

    Fix: Check LED long leg to resistor, short leg to GND, and confirm LED_PIN is 2 in the code.

  • Upload fails after wiring

    Likely cause: A wire may be pulling a boot-sensitive pin into the wrong state during reset.

    Fix: Use GPIO27 for the button and GPIO2 for the LED as shown. Unplug and recheck wiring.

FAQs

  • Why is my ESP32 button backwards?

    With INPUT_PULLUP, the pin reads HIGH when the button is not pressed and LOW when the button is pressed. That feels backwards at first, but it is normal and reliable.

  • Do I need an external resistor for this button?

    No. This mission uses the ESP32 internal pull-up resistor by setting pinMode(BUTTON_PIN, INPUT_PULLUP). The button connects the pin to GND when pressed.

  • Why does the LED flicker or change by itself?

    That usually means the button input is floating. Use INPUT_PULLUP, connect one side of the button to GPIO, and connect the other side to GND.

  • Can I use any ESP32 GPIO for a button?

    Many GPIO pins work, but avoid boot strapping pins while learning. GPIO27 is a safe beginner choice for this mission.

Mission Complete!

Your ESP32 can now listen.

You learned the most important idea behind interactive electronics: read an input, make a decision, then control an output. This pattern powers alarms, robots, smart locks, thermostats, dashboards, and almost every real ESP32 project.

  • Read digital input with digitalRead()
  • Use INPUT_PULLUP correctly
  • Avoid floating input pins
  • Control an LED from a button state
  • Use Serial Monitor to verify hardware behavior

What This Unlocks

Unlocked Components

Unlocked Projects

Continue Learning

Continue Your Journey