Digital I/O
Digital means two states: HIGH (5V, on, 1) or LOW (0V, off, 0). No in-between. Buttons, motion sensors, and LEDs live in this world.
Output: lighting an LED
Wire: Uno pin 13 → 220Ω resistor → LED long leg (+); LED short leg (−) → GND. (The built-in LED needs no wiring, but wiring your own teaches the circuit.)
void setup() {
pinMode(13, OUTPUT);
}
void loop() {
digitalWrite(13, HIGH); // LED on
delay(500);
digitalWrite(13, LOW); // LED off
delay(500);
}
Why the resistor? An LED without one draws as much current as it can — briefly very bright, then dead, possibly taking the pin with it. The 220Ω resistor limits current to ~15mA, safely under the pin's ~20mA limit. No LED without a resistor (except the built-in one — it has its own).
Input: reading a button
Wire: button between pin 2 and GND. No extra resistor needed — we use the chip's built-in one:
const int BUTTON_PIN = 2;
const int LED_PIN = 13;
void setup() {
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(LED_PIN, OUTPUT);
}
void loop() {
int buttonState = digitalRead(BUTTON_PIN);
if (buttonState == LOW) {
digitalWrite(LED_PIN, HIGH); // pressed → LED on
} else {
digitalWrite(LED_PIN, LOW);
}
}
Why does pressed read LOW? INPUT_PULLUP connects the pin
internally to 5V through a resistor, so it reads HIGH when idle.
Pressing the button connects it to GND, dragging it LOW. Backwards
from intuition, but it means the button needs no external parts —
one wire to GND and you're done.
Debouncing: buttons lie
A button press isn't one clean on/off — the metal contacts bounce, producing a burst of rapid on/off flickers over a few milliseconds. Your loop runs fast enough to see each bounce as separate presses. For "LED follows button" you won't notice; for "count presses" you must.
The simple fix: after seeing a change, ignore further changes for ~50ms:
const int BUTTON_PIN = 2;
int pressCount = 0;
int lastState = HIGH;
unsigned long lastDebounceTime = 0;
void setup() {
pinMode(BUTTON_PIN, INPUT_PULLUP);
Serial.begin(9600);
}
void loop() {
int reading = digitalRead(BUTTON_PIN);
if (reading != lastState) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > 50) {
if (reading == LOW && lastState == HIGH) {
pressCount++;
Serial.print("Presses: ");
Serial.println(pressCount);
}
}
lastState = reading;
}
(Uses Serial — covered properly in Serial. For now:
it prints the count to your computer.)
digitalRead / digitalWrite cheat sheet
| Call | Does |
|---|---|
pinMode(pin, OUTPUT) |
Pin will drive HIGH/LOW |
pinMode(pin, INPUT) |
Pin reads external signal (needs external resistor) |
pinMode(pin, INPUT_PULLUP) |
Pin reads, idle = HIGH |
digitalWrite(pin, HIGH/LOW) |
Set output |
digitalRead(pin) |
Returns HIGH or LOW |
Next: Analog