Learning Goals 5 min
By the end of this lesson you will be able to:
- Wire a 4-pin push button straddling the breadboard trough, with a 10 kΩ pull-down resistor that anchors the input pin to GND when the button is released.
- Set a pin as
INPUTinsetup()withpinMode(pin, INPUT), and read its state withdigitalRead(pin), which returnsHIGHorLOW. - Write a sketch where pressing the button makes the onboard
LLED light up — by passing the result ofdigitalReadstraight intodigitalWriteon pin 13.
Warm-Up 10 min
For fifteen lessons every pin you've touched has been an output — you decided HIGH or LOW, the world reacted. Today the direction flips. The pin becomes an input — the world (a button) decides HIGH or LOW, and your sketch reacts.
Quick-fire puzzle
Priya holds up the small 4-pin push button from her starter kit and asks three questions before wiring anything:
- If she connects 5 V straight to a digital pin through the button, and presses it — what voltage is on the pin? What does the pin read?
- Now she releases the button. The pin is no longer connected to 5 V. Is it connected to anything else? What might its voltage be?
- If a pin is connected to nothing at all, what voltage does it actually have?
Reveal the answer
- 5 V. The button is closed; 5 V reaches the pin. The pin reads
HIGH. - Nothing else. The button is open, breaking the only connection. The pin is dangling — not connected to 5 V, not connected to GND, just sitting there.
- It's a mystery — and that's the problem. A floating pin picks up tiny electrical noise from the air, from your finger near the wire, from nearby motors. It might read
HIGHone moment andLOWthe next, completely randomly. Floating pins are not allowed for reliable circuits.
The fix: add a second wire that always pulls the pin to a known voltage when the button is open. That second wire goes through a pull-down resistor to GND — today's main idea.
New Concept 20 min
The big idea — inputs need to know what to read when nothing's pressed
An Arduino digital pin can be set to one of two roles:
OUTPUT— your sketch chooses the pin's voltage withdigitalWrite. You've been doing this since L01-07.INPUT— the outside world chooses the pin's voltage. Your sketch reads it withdigitalRead. New today.
An input pin is happy with either 5 V (reads HIGH) or 0 V (reads LOW). What it cannot handle is nothing — a floating pin reads garbage. Every input pin in every reliable circuit must be tied to a known voltage at all times, even when the user isn't pressing the button.
The pull-down resistor
A pull-down resistor is a 10 kΩ resistor connecting the input pin to GND. It "pulls" the pin to LOW when nothing else is pulling it the other way. The button's job is then to occasionally pull the pin HIGH by connecting it to 5 V.
- Button open (not pressed): 5 V is isolated from the pin. The pull-down resistor quietly drains any noise to GND. Pin reads
LOW. - Button closed (pressed): 5 V flows through the button to the pin. The pull-down resistor is still there, but the button is "stronger" — current flows from 5 V to GND through the resistor, and the pin sits near 5 V. Pin reads
HIGH.
Why 10 kΩ? Two reasons. (1) It's big enough that almost no current is wasted: when the button is pressed, only 0.5 mA flows from 5 V to GND through the resistor — practically free. (2) It's small enough to be "stronger" than the air around the pin, so it dominates over any stray noise.
The push button itself
The button in your starter kit has four pins arranged in a small square. Internally:
- The two pins on the top side are always connected to each other.
- The two pins on the bottom side are always connected to each other.
- Press the button → the top pair connects to the bottom pair. Release → that connection breaks.
You only need to wire one pin from each pair. The other two pins are duplicates and stay empty. To make sure the top pair and bottom pair are different tie strips on the breadboard, the button must straddle the trough — top pins in the top half (row D), bottom pins in the bottom half (row F).
Wiring map
| From | To | Wire / colour |
|---|---|---|
Arduino 5V | Breadboard A11 | Red — supplies +5 V to the top side of the button |
| Button top-left | Breadboard D11 | (component pin) |
| Button top-right | Breadboard D14 | (empty — unwired duplicate) |
| Button bottom-left | Breadboard F11 | (component pin — signal side) |
| Button bottom-right | Breadboard F14 | (empty — unwired duplicate) |
Arduino D7 | Breadboard H11 | Yellow — reads the signal from the button's bottom side |
| 10 kΩ resistor lead 1 | Breadboard G11 | (component, same tie strip as the signal) |
| 10 kΩ resistor lead 2 | Breadboard G16 | (component, separate tie strip) |
Breadboard H16 | Arduino GND | Black — closes the pull-down path |
Two new pieces of code
| Function | What it does |
|---|---|
pinMode(pin, INPUT) | Tells the chip the pin will be read, not written. The INPUT constant is the partner of the OUTPUT you've been using. |
digitalRead(pin) | Returns HIGH if the pin is at 5 V, LOW if it's at 0 V. Use it on any pin you've set as INPUT. |
The trick that avoids needing if/else
You haven't met conditional statements yet — those come in L01-20. But you don't need them today, because HIGH and LOW mean the same thing whether you're reading a pin or writing one. So you can take the value digitalRead returns and pass it straight to digitalWrite on the onboard LED:
digitalWrite(13, digitalRead(BUTTON_PIN));If the button reads HIGH, the onboard LED writes HIGH → LED on. If the button reads LOW, the LED writes LOW → LED off. One line, one mirror.
No new external LED today
We control the onboard L LED on pin 13 — the one built into the Arduino board itself, between the digital headers. No need to wire an external LED. This keeps today's focus 100% on the input side of the circuit.
Why it matters
Every interactive Arduino project — game controller, alarm panel, smart switch, robot remote — starts with the pattern you'll build today. Read a digital input, make a decision, drive an output. Today is the input half of that pipeline; you already know the output half.
Worked Example 20 min
Goal: build the button circuit, then write a sketch that makes the onboard LED light up when you press the button.
The wiring
The same circuit as a schematic
The vertical schematic reads top to bottom: 5 V → button → junction (where D7 takes off) → 10 kΩ → GND. Press the button and the junction sees 5 V; release it and the junction is dragged down to GND by the resistor.
The sketch
const int BUTTON_PIN = 7;
const int LED_PIN = 13; // onboard L LED, no wiring needed
void setup() {
pinMode(BUTTON_PIN, INPUT);
pinMode(LED_PIN, OUTPUT);
}
void loop() {
digitalWrite(LED_PIN, digitalRead(BUTTON_PIN));
}Expected behaviour
- Plug in the Arduino. The onboard
LLED stays dark. - Press the button. The onboard LED lights up immediately.
- Release the button. The LED goes off immediately.
- Hold the button for 5 seconds. The LED stays on for those 5 seconds, then off as soon as you let go.
If the LED stays dark no matter how hard you press: check the button is straddling the trough (top pair in row D, bottom pair in row F — not all four in the top half). If the LED stays on even when you don't touch the button: the pull-down resistor isn't doing its job; check that it bridges the signal tie strip and a GND-bound tie strip.
Trace the trick
The one-line loop() body is doing two things at once:
digitalRead(BUTTON_PIN)looks at pin 7 and returns eitherHIGHorLOW.- That value flows directly into
digitalWrite(LED_PIN, …)as its second argument.
So when the button is pressed, the line becomes digitalWrite(13, HIGH) — LED on. When released, it becomes digitalWrite(13, LOW) — LED off. The loop runs thousands of times per second, so the mirror feels instant.
Try It Yourself 20 min
Goal: Make the LED behave opposite to the button — on when released, off when pressed. (An "inverted" mirror.)
Two things you could do. Pick one and explain the other in writing:
- Swap the wiring: the wire that goes from
5Vto the button's top side and the wire that goes fromGNDthrough the resistor to col 16 swap places. Now the resistor pulls the pin up to 5 V by default, and the button connects it down to GND when pressed. (You've just invented "pull-up"! L01-17 will make it official.) - Keep the wiring the same, but read the button into a variable first and use
!(NOT) in the write:
void loop() {
int state = digitalRead(BUTTON_PIN);
digitalWrite(LED_PIN, !state); // the ! flips HIGH ↔ LOW
}Question: Which version feels cleaner — change the hardware or change the code? Why? ____
Goal: Store the button's state in a named variable before using it. This is a stepping stone to L01-18 (debouncing) and L01-19 (state-change detection), both of which require a stored state.
const int BUTTON_PIN = 7;
const int LED_PIN = 13;
void setup() {
pinMode(BUTTON_PIN, INPUT);
pinMode(LED_PIN, OUTPUT);
}
void loop() {
int buttonState = digitalRead(BUTTON_PIN);
digitalWrite(LED_PIN, buttonState);
}Questions:
- The behaviour is identical to the Worked Example. So why might a future-you prefer this version? ____ (Hint: in L01-18 we'll want to compare the current button state to a previous one. Storing it lets us do that.)
buttonStateis a plainint, not aconst int. Why? ____ (Hint: every pass ofloop()the value might change.)
Goal: Light up the onboard LED for twice as long as the button is held. Press for 1 second → LED stays on for 2 seconds. Press for 5 seconds → LED stays on for 10 seconds. (Hint: you don't know millis() yet, so use a small delay() in the loop to extend each "snapshot" of the button state.)
One simple approach: every time the button reads HIGH, light the LED and delay; every time it reads LOW, light the LED and delay anyway (extending the "on" period by one extra cycle). Use the 🟡 task's stored-state version as a starting point.
void loop() {
int buttonState = digitalRead(BUTTON_PIN);
digitalWrite(LED_PIN, buttonState);
delay(10); // hmm — this just slows the mirror, not extends it
}That isn't quite the goal. The honest answer: extending the on-time properly needs control flow you don't have yet (an if from L01-20, or a stored timestamp from L01-26-area lessons). For today, try the closest version you can — even if it ends up just being a slower mirror — and write down on paper what tool you'd add to do it properly.
Question: What new piece of the language would let you say "if the button was pressed, keep the LED on for 2 seconds and then read again"? ____
Mini-Challenge 15 min
Diagnose three broken circuits
You're going to look at three "broken" versions of today's button circuit. For each one, predict what the onboard LED will do before you build it, then build it and check. Your job is to explain why each failure happens — not to fix it (yet).
- Version A: Remove the 10 kΩ pull-down resistor entirely. Leave everything else exactly as the Worked Example.
- Predict: When you don't touch the button, what does the LED do? When you place a finger near the breadboard (without pressing), what does the LED do? Does pressing the button still cause the LED to light? ____
- Version B: Re-plug the button so all four pins are in the top half of the board (D11, D14, E11, E14 — same columns, but bottom pair moved up from row F to row E so it stays in the top-half tie strip).
- Predict: What does the LED do at all times — pressed or released? Why? ____
- Version C: Keep the Worked-Example wiring but accidentally swap the 5 V wire and the GND wire — so 5 V goes through the resistor to col 16 and GND goes to A11.
- Predict: What does the LED do when you press the button? What about when you release it? Is this a useful circuit, or a useless one? ____
Reveal the answers
- Version A — no pull-down. The pin floats when the button is open. The LED flickers randomly, often lighting up when your finger comes near the wire (your body acts as a tiny antenna). Pressing the button does still light the LED (5 V still reaches the pin), but the released state is unreliable. This is exactly the bug the pull-down resistor exists to prevent.
- Version B — button in top half only. The LED stays on permanently from the moment power is applied. Reason: the column tie strip for col 11 (top half) connects D11 to E11 inside the breadboard. So the button's top pair and bottom pair are now both on the same col 11 tie strip — they were always connected, even before pressing. The "switch" effect is short-circuited. This is exactly why the button must straddle the trough.
- Version C — swapped supply. You've accidentally built a pull-up circuit (the partner of pull-down). The LED is on when the button is released and off when pressed — the mirror is inverted. The circuit isn't useless; it's just the same idea wired the other way round. We'll learn the cleaner version of this (without the external resistor at all) in L01-17 "INPUT_PULLUP".
Recap 5 min
An input pin reads HIGH or LOW from the outside world. To make the reading reliable, the pin must be tied to a known voltage at all times — a pull-down resistor (10 kΩ to GND) gives it a default LOW, and the button connects it temporarily to 5 V. In code, pinMode(pin, INPUT) declares the pin's role and digitalRead(pin) returns its state — which you can pass straight into digitalWrite() on an output pin to make one mirror the other.
- Input pin
- A digital pin whose voltage is set by the outside world (a button, a sensor) and read by your sketch. The partner of an output pin.
- pinMode(pin, INPUT)
- Declares the pin as an input. Goes in
setup(), just likepinMode(pin, OUTPUT). - digitalRead(pin)
- Returns the pin's current state — either
HIGH(≈ 5 V) orLOW(≈ 0 V). Use only on pins declared asINPUT. - Pull-down resistor
- A 10 kΩ resistor connecting an input pin to GND. Pulls the pin to
LOWwhen nothing else is driving it — preventing floating. - Floating pin
- An input pin not connected to either 5 V or GND. Its voltage is undefined and its readings are random. Always avoid by adding a pull-down (or pull-up) resistor.
- Straddling the trough
- Placing a 4-pin button so its top pair sits in the top half of the breadboard and its bottom pair in the bottom half. Required so the trough breaks the tie strip between the two pairs.
Homework 5 min
Build a "press counter" — almost. Using only today's tools, write a sketch that shows when the button is being held by lighting the onboard LED, and add a single line that prints the button's state to the Serial Monitor every loop.
You haven't met Serial properly yet (that's L01-23), but it's safe to try the form below as a sneak preview. Open the Serial Monitor in the Arduino IDE (top-right magnifying-glass icon) at 9600 baud while the sketch runs.
const int BUTTON_PIN = 7;
const int LED_PIN = 13;
void setup() {
pinMode(BUTTON_PIN, INPUT);
pinMode(LED_PIN, OUTPUT);
Serial.begin(9600);
}
void loop() {
int buttonState = digitalRead(BUTTON_PIN);
digitalWrite(LED_PIN, buttonState);
Serial.println(buttonState);
delay(50);
}You should see a long column of 0s when the button is released, switching to a long column of 1s when held. (HIGH = 1, LOW = 0 — they're the same value in two notations.)
Also: a design reflection on paper.
- If you wanted the LED to stay on for 2 seconds after release (like a doorbell that keeps ringing for a moment), name the two new pieces of the language you'd need. (Hint: one for "make a decision", one for "remember when something happened".) ____
- The pull-down resistor "wastes" 0.5 mA whenever the button is pressed. The Arduino UNO can supply about 200 mA across all pins. How many pressed-button circuits could you have on one Arduino before the budget runs out? ____ (Hint: 200 ÷ 0.5.)
Bring back next class:
- The saved
.inofile (call itbutton-mirror). - A phone photo of the Serial Monitor window showing the 0/1 column while you held the button.
- Your reflection answers on a notebook page.
Heads up for next class: in L01-17 "INPUT_PULLUP" you'll meet a built-in resistor inside the Arduino itself that replaces today's external 10 kΩ — saving you one component and one wire on every future button. Today's circuit is the canonical version; tomorrow's is the shortcut.