What you will learn
  • Wire a switch between a digital input and ground.
  • Explain a floating input and internal pull-up.
  • Interpret active-low button readings.
  • Control an LED from the button state.
  • Distinguish state reading from counting press events.

Before you begin

Build the resistor-protected external LED in ARD03 first. This project keeps that D8 circuit and adds one switch.

A released button still needs a defined voltage

A button seems to have two obvious states: pressed and released. Electrically, however, opening a switch can leave its input wire disconnected from both power and ground. That floating input may respond to electrical interference and report apparently random changes.

A pull-up resistor provides a weak connection from the input to the logic supply. When the switch is open, the input reads HIGH. When the switch closes to ground, the input reads LOW. The resistor limits the current through that connection.

The Uno R3 can enable an internal pull-up using INPUT_PULLUP. We therefore need no separate pull-up resistor for this example. The LED still needs its own current-limiting resistor because that resistor solves a different problem.

The convention is called active-low: a LOW reading represents the event we care about. LOW is an electrical interpretation, not the English word false. Your program decides that this level means the button is pressed.

Use the existing LED and add the button

Unplug USB. Retain the circuit D8 → 330 Ω → red LED anode, with LED cathode → GND. Add a push button between D2 and GND. Do not connect this button to 5V.

Four-legged tactile switches often contain two permanently connected pairs. Pressing joins the pairs. With power disconnected, use a continuity meter or the switch’s diagram to find contacts that change from open to connected when pressed. Many switches fit across a breadboard’s central gap, but physical fit alone does not prove the correct terminals were chosen.

All grounds in this small circuit connect to Uno GND. Inspect the breadboard with USB removed, then reconnect only USB. No external supply, motor or relay belongs in this build. The Uno reference is the 5 V Uno R3; a different board requires checking its electrical specifications.

PartConnection
Uno R3 and USB data cableController and power
Red LED with 330 Ω resistorD8 → resistor → anode; cathode → GND
Normally open push buttonD2 to one switching contact; other contact to GND
Breadboard and jumpersKeep LED legs in separate connected rows

Translate the electrical state into a meaning

Upload this Arduino C/C++ sketch. It requires no extra library. Open Serial Monitor at 9600 baud to see the interpretation alongside the LED.

cpp
const byte buttonPin = 2;
const byte indicatorPin = 8;

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

void loop() {
  bool pressed = digitalRead(buttonPin) == LOW;
  digitalWrite(indicatorPin, pressed ? HIGH : LOW);
  Serial.println(pressed ? "pressed" : "released");
  delay(50);
}

digitalRead() returns the pin state. Comparing it with LOW produces a Boolean meaning pressed. The conditional expression chooses HIGH when pressed is true and LOW otherwise. Serial prints the same meaning for inspection. The 50-millisecond pause reduces repeated messages; it is not a complete debounce algorithm.

Expected result: The LED lights while the button is held. Serial Monitor shows pressed during a press and released after release, about twenty messages per second.

Why this is not yet a click counter

A real mechanical switch can bounce: its contacts briefly open and close several times during one human press. For a lamp that follows the held state, a brief flicker may not be noticeable. A program that increments a counter on every transition can count several presses.

There is another counting trap even with a perfect switch. This loop reads the button repeatedly. If you increment every time pressed is true, holding the button will add many counts. You need edge detection, which recognizes a change from released to pressed, and debouncing, which rejects rapid contact noise.

A common debounce design remembers the latest raw reading and when it changed. It accepts a new stable state only after that reading remains unchanged for a short interval, such as 25 milliseconds. The suitable interval depends on the switch and required responsiveness. Arduino’s Debounce and State Change Detection examples demonstrate these distinct techniques.

Keep this article’s purpose narrow: reliably interpret a held state. Build a counter as the independent extension only after you can explain why state, transition and debounced event mean different things.

Test the logic, then the wiring

With the button released, expect released and an unlit LED. Press and hold for two seconds: expect pressed throughout and an illuminated LED. Release and repeat ten times. Write down whether the displayed state and light agree.

If the serial text changes correctly but the LED does not, the input side probably works; inspect the LED circuit, polarity and D8 selection. If the output always says pressed, disconnect USB and inspect whether D2 is permanently connected to ground through the switch’s same-side contacts.

If the text is garbled, match the Serial Monitor speed to 9600. If the state fluctuates with the button untouched, confirm the sketch uses INPUT_PULLUP and the ground wire is connected. A software message gives you evidence about one part of the system; it does not automatically prove every wire is right.

A useful requirement is observable: the LED should follow a held button within roughly one loop period. Avoid stating that the circuit detects every arbitrarily short pulse. A pulse that occurs entirely between two readings may be missed.

Important terms

Floating input
An input without a defined electrical level.
Pull-up resistor
A resistor that gently connects an input to its logic supply.
Active-low
A convention in which a LOW signal represents the active condition.
Boolean
A value with two possibilities: true or false.
Debouncing
Filtering unwanted transitions caused by switch contact movement.
Edge detection
Recognizing a transition rather than repeatedly reading a held state.

Mini project: Build a button-state truth table

  1. Record expected readings for open and pressed states before connecting power.
  2. Build and upload the circuit and program.
  3. Hold the button for two seconds and compare LED behavior with serial text.
  4. Repeat ten presses and record any disagreement.
  5. Finish by explaining why LOW means pressed in this circuit.

Common mistakes and debugging

  • Using INPUT without a pull-up or pull-down: enable INPUT_PULLUP for the wiring shown.
  • Choosing two permanently connected switch legs: inspect the unpowered switch contacts.
  • Calling the 50-millisecond pause debouncing: it slows sampling but does not require a stable transition.
  • Counting once per loop while held: detect an edge before incrementing a click counter.

Independent challenge

Using the official debounce and state-change examples, design a counter that adds exactly one per press. Test long holds and rapid presses separately before displaying the count.

Check your understanding: 10 questions

  1. What does the released input read here?

  2. Where does pressing the button connect D2?

  3. Why does the LED still need a resistor?

  4. What is switch bounce?

  5. Why is reading a held state insufficient for a press counter?

  6. In your own words, what does “Floating input” mean?

  7. In your own words, what does “Pull-up resistor” mean?

  8. In your own words, what does “Active-low” mean?

  9. In your own words, what does “Boolean” mean?

  10. In your own words, what does “Debouncing” mean?

Quiz answers

Reveal all 10 answers after your attempt
  1. HIGH, because the internal pull-up defines the open-switch state.
  2. To ground.
  3. The pull-up controls input bias; it does not limit current through the separate LED output circuit.
  4. Several brief electrical transitions during one physical contact movement.
  5. The same press is read on many loop iterations; counting needs transition detection and usually debouncing.
  6. An input without a defined electrical level.
  7. A resistor that gently connects an input to its logic supply.
  8. A convention in which a LOW signal represents the active condition.
  9. A value with two possibilities: true or false.
  10. Filtering unwanted transitions caused by switch contact movement.

Summary

A defined input level makes a button understandable to software. Translate that level into a meaningful variable, then test input readings and output behavior independently.

Continue learning

ARD05 moves beyond switches to measurements that change across a range.

Choose a connected learning path

Sources and further reading

Prepared 2026-09-18. Editorial draft; primary documentation consulted. Hardware build not bench-tested; code has not been executed on the reference board.

GO DEEPER

Extra reading & source documents

Optional reading alongside the lessons. These sources do not add to your course lesson count.

Explore the AI model guides →