Lesson 3 of 13
Push a button
Objective: Read a digital input with digitalRead() and use it to control an output.
Press ▶ Run first: while the sketch is stopped, nothing reads the button.
The signal trace appears while the sketch runs: it draws D2 and D13 over the last 4 seconds.
Stage 1 of 7 · What am I building?
Explore
A button is the simplest input. The board reads pin D2 and decides what to do with the LED on D13. Select each part on the circuit, or below. Notice the resistor inside the chip: it is the reason this circuit needs no resistor for the button.
Pick a part. 0/9 inspected.
Before you start (optional refreshers)
Voltage, current and resistance
Voltage pushes, resistance restricts, current is the flow. Ohm's law ties them together: I = V ÷ R.
Variables and constants
A variable is a named value that can change; `const` makes a name for a value that never changes. Declared outside every function (global), a variable keeps its value between passes of loop(); declared inside loop(), it starts again on every pass.
Digital HIGH and LOW
A digital pin is either HIGH (about 5 V on an Uno) or LOW (0 V). digitalWrite() sets an output; digitalRead() reports an input.
Timing and delay()
delay(ms) pauses the whole program. Nothing else happens while it waits, so a blink lasts ON delay + OFF delay.
New ideas in this lesson
Digital input
digitalRead() reports whether an input pin is HIGH or LOW. An unconnected input 'floats' and reads randomly.
Pull-up resistors and active-low inputs
INPUT_PULLUP holds a pin HIGH through an internal resistor. A button to GND pulls it LOW when pressed, so LOW means pressed.
Conditional logic
if (condition) { … } else { … } chooses what to do from a reading. The same test runs on every pass of loop().
Detecting a change (edge)
Compare this reading with the last one to act once, at the moment the button goes from released to pressed, instead of on every pass of loop() while it is held.
Timing with millis()
millis() is the number of milliseconds since the board started, as an unsigned long. Saving it and comparing later measures how long has passed without stopping the sketch, unlike delay(). It rolls over to 0 after about 49.7 days; now - start >= interval still gives the right answer then, because unsigned subtraction rolls over too.
Switch bounce and debouncing
A button's metal contacts spring open and closed a few times in the first milliseconds of a press or release. Debouncing ignores further changes for a short time after accepting one, so one press counts once.
Build it for real · Arduino Uno R3
You need
- Arduino Uno R3 (or compatible) and its USB cable
- Breadboard and jumper wires
- Push button (4-leg tactile)
- LED
- 220 Ω resistor
Wiring
- Place the button across the breadboard's centre gap.
- One button leg → D2; the diagonally opposite leg → GND. No external resistor: INPUT_PULLUP provides it.
- LED: D13 → 220 Ω → LED long leg; short leg → GND.
Before you power up: Never wire a button straight between 5V and GND: pressing it would short the supply. With INPUT_PULLUP it goes between the pin and GND.
Tip: Not working? Check you used diagonally opposite legs: two legs on the same side may already be joined inside the button.
The lab models ideal parts. Real circuits add tolerances, noise and loose wires, so check your wiring against this list before you plug in.
// Push a button to light an LED
// Button: pin 2 to GND, using the internal pull-up resistor
// LED: pin 13 through a 220 ohm resistor to GND
const int buttonPin = 2;
const int ledPin = 13;
void setup() {
pinMode(buttonPin, INPUT_PULLUP); // reads HIGH when released
pinMode(ledPin, OUTPUT);
}
void loop() {
int reading = digitalRead(buttonPin);
if (reading == LOW) { // pressed?
digitalWrite(ledPin, HIGH);
} else {
digitalWrite(ledPin, LOW);
}
}Press ▶ Run, then press the button to see which branch of the if-statement runs.