Project: blink and button
What you’ll build
An LED you control with code, then with a push button, then a toggle switch made from code: press once for on, press again for off. This is exactly how a robot reads a bump sensor.
Parts
| Part | Qty |
|---|---|
| Arduino UNO (or compatible) + USB cable | 1 |
| Breadboard | 1 |
| LED (any colour) | 1 |
| Resistor: 330 Ω (UNO R3 / clones) or 470 Ω–1 kΩ (UNO R4) | 1 |
| Push button (4-leg tactile) | 1 |
| Jumper wires | 4 |
Wiring
Arduino pin 8 ──── resistor ──── LED long leg (+) LED short leg (−) ──── GND
Arduino pin 2 ──── button ──── GND- Unplug the USB cable while wiring.
- Connect an Arduino GND pin to the breadboard’s blue − rail.
- Put the LED in the breadboard. Connect its short leg to the − rail.
- Connect the resistor from the LED’s long leg to an empty row, then a jumper from that row to pin 8.
- Place the button across the centre gap so its legs sit in two rows, say rows 20 and 22. Connect row 20 to pin 2 and row 22 to the − rail, both on the same side of the gap. (The legs facing each other across the gap are always joined; pressing connects row 20 to row 22.)
If it doesn’t work
| Symptom | Check |
|---|---|
| LED never lights | LED backwards? GND wired? Code uses pin 8 and the wire is on pin 8? |
| LED always on (step 2) | Button wired to 5V instead of GND, or INPUT instead of INPUT_PULLUP |
| Button does nothing | Button rotated 90°. Its legs are joined in pairs, so try rotating it |
| Toggle flips twice or randomly | Increase the debounce delay to 100 |
Still stuck? Work through My robot doesn’t work.
Step 1: blink an external LED
const int LED = 8;
void setup() { pinMode(LED, OUTPUT);}
void loop() { digitalWrite(LED, HIGH); delay(500); digitalWrite(LED, LOW); delay(500);}You should see: your LED blinking twice per second.
Step 2: light while the button is held
const int LED = 8;const int BUTTON = 2;
void setup() { pinMode(LED, OUTPUT); pinMode(BUTTON, INPUT_PULLUP); // pin is HIGH until the button connects it to GND}
void loop() { if (digitalRead(BUTTON) == LOW) { // LOW means pressed digitalWrite(LED, HIGH); } else { digitalWrite(LED, LOW); }}Why INPUT_PULLUP, and why is pressed LOW?
An input pin connected to nothing “floats” and reads random values. INPUT_PULLUP turns on a resistor inside the Arduino that gently pulls the pin up to 5 V (HIGH). Pressing the button connects the pin to GND, so it reads LOW. It feels backwards at first, but it means no extra resistor is needed.
You should see: the LED is on only while you hold the button.
Step 3: a toggle switch in code
const int LED = 8;const int BUTTON = 2;
bool ledOn = false;bool wasPressed = false;
void setup() { pinMode(LED, OUTPUT); pinMode(BUTTON, INPUT_PULLUP);}
void loop() { bool pressed = (digitalRead(BUTTON) == LOW);
if (pressed && !wasPressed) { // only at the moment the button goes down ledOn = !ledOn; // flip: on becomes off, off becomes on digitalWrite(LED, ledOn ? HIGH : LOW); delay(50); // ignore "bounce" for 50 ms } wasPressed = pressed;}Two new ideas:
- Edge detection: we act only when the button changes from not-pressed to pressed, not the whole time it’s held.
- Debouncing: metal contacts inside a button bounce for a few milliseconds, which looks like several fast presses. The short
delay(50)ignores them.
You should see: each press flips the LED on or off.
Simulate it first (optional)
No parts, or want to check your wiring? Build the whole project in the virtual Arduino:
- Press Start simulator below.
- Click the diagram.json tab, select everything in it, and replace it with the code below. The LED, resistor and button appear already wired, exactly like the diagram above.
- Paste each step’s code into sketch.ino and press the green ▶. Click the virtual button to press it.
{ "version": 1, "author": "RoboLearn", "editor": "wokwi", "parts": [ { "type": "wokwi-arduino-uno", "id": "uno", "top": 0, "left": 0, "attrs": {} }, { "type": "wokwi-led", "id": "led1", "top": -120, "left": 120, "attrs": { "color": "red" } }, { "type": "wokwi-resistor", "id": "r1", "top": -40, "left": 170, "attrs": { "value": "330" } }, { "type": "wokwi-pushbutton", "id": "btn1", "top": -110, "left": 260, "attrs": { "color": "green" } } ], "connections": [ [ "uno:8", "r1:2", "green", [] ], [ "r1:1", "led1:A", "green", [] ], [ "led1:C", "uno:GND.1", "black", [] ], [ "btn1:1.l", "uno:2", "blue", [] ], [ "btn1:2.l", "uno:GND.1", "black", [] ] ], "dependencies": {}}Runs on Wokwi, free, no account needed.
SOSEasy
Blink · · · — — — · · · in Morse code (short = 200 ms, long = 600 ms) on the pin 8 LED.
See the SOS answer in the Arduino UNO lesson’s Practice tab, and change LED_BUILTIN to 8.
Speed controlMedium
Each button press makes the blink faster; after the fastest speed it goes back to slow. Keep the blink time in a variable and change it on each new press.
Show an answer
const int LED = 8, BUTTON = 2;int wait = 800;bool wasPressed = false;
void setup() { pinMode(LED, OUTPUT); pinMode(BUTTON, INPUT_PULLUP);}
void loop() { bool pressed = digitalRead(BUTTON) == LOW; if (pressed && !wasPressed) { wait = wait / 2; if (wait < 50) wait = 800; } wasPressed = pressed; digitalWrite(LED, HIGH); delay(wait); digitalWrite(LED, LOW); delay(wait);}The button is only checked between blinks, so at slow speeds you may need to hold it briefly. The traffic-light and reaction-game challenges fix this with millis().
Traffic lightMedium
Add yellow and green LEDs on pins 9 and 10 and cycle red (3 s) → green (3 s) → yellow (1 s).
Reaction gameHard
The LED lights after a random wait of 1–5 s. Print how many milliseconds you took to press the button.
random(1000, 5000) picks the wait; millis() gives the time now.
Show an answer
const int LED = 8, BUTTON = 2;
void setup() { pinMode(LED, OUTPUT); pinMode(BUTTON, INPUT_PULLUP); Serial.begin(9600); randomSeed(analogRead(A0));}
void loop() { digitalWrite(LED, LOW); delay(random(1000, 5000)); digitalWrite(LED, HIGH); unsigned long start = millis(); while (digitalRead(BUTTON) == HIGH) {} // wait for the press Serial.print("Reaction time: "); Serial.print(millis() - start); Serial.println(" ms"); delay(1500);}Quick check
Finished this lesson?