Learning Goals 5 min
By the end of this lesson you will be able to:
- Wire three LEDs — one red, one yellow, one green — to three separate digital pins on the same breadboard, each with its own 220 Ω current-limiting resistor.
- Use the breadboard's − rail as a shared GND bus so that all three LEDs return through a single GND wire to the Arduino.
- Declare three named pin constants (
RED_PIN,YELLOW_PIN,GREEN_PIN) and write a sketch that lights each LED on its own pin, independently of the others.
Warm-Up 10 min
Last lesson we replaced the literal 13 with the name LED_PIN. The sketch was easier to read and easier to change. Today we have three pins to keep track of — and naming becomes essential, not optional.
Quick-fire puzzle
Wei Jie wants to wire three LEDs — red on pin 9, yellow on pin 10, green on pin 11 — onto the same breadboard. Before peeking at today's diagram, predict:
- How many 220 Ω resistors does he need? Why is sharing one resistor between two LEDs a bad idea?
- If each LED needs a wire back to
GND, does Wei Jie need three separate black wires running all the way to the Arduino'sGNDpin — or is there a tidier way? - In Wei Jie's sketch, how many
pinMode()calls willsetup()contain? How manydigitalWrite()calls happen each time he wants to turn an LED on?
Reveal the answer
- Three resistors — one per LED. Two LEDs sharing one resistor will not split the current evenly; the slightly "thirstier" LED steals most of it and burns out within minutes.
- The tidy way: plug all three black wires into the breadboard's − rail, then run a single black wire from the − rail back to the Arduino's
GNDpin. The − rail acts as a shared "GND bus". - Three
pinMode()calls — one per pin. And onedigitalWrite()call per LED you want to switch. To turn all three on, you make three calls.
New Concept 20 min
The big idea — three of everything (except GND)
To drive three LEDs independently you need:
- Three Arduino pins — one per LED. Today we'll use
D9,D10andD11. - Three resistors — one per LED, in series. Never share.
- Three LEDs — each in its own column pair on the breadboard.
- One shared GND path — running through the breadboard's − rail.
The − rail trick is the key new idea. Without it, you'd have a tangle of three GND wires fighting for space at the Arduino's single GND pin. With it, the breadboard handles the gathering and one tidy wire returns to the Arduino.
Wiring map for today's three modules
Each "module" is a self-contained LED + resistor sub-circuit. Three modules sit side by side across the breadboard's top half.
| Module | Signal pin → row A | Resistor (row D) | LED legs (row B) | GND return |
|---|---|---|---|---|
| 1 — Red | D9 → A1 | D1 – D6 | cathode B5, anode B6 | C5 → − rail |
| 2 — Yellow | D10 → A11 | D11 – D16 | cathode B15, anode B16 | C15 → − rail |
| 3 — Green | D11 → A21 | D21 – D26 | cathode B25, anode B26 | C25 → − rail |
| Shared: | − rail → Arduino GND | |||
The sketch — three names at the top
Three pins means three constants. Give each one a name based on the LED's colour, not the pin number — the colour is what matters in the logic.
const int RED_PIN = 9;
const int YELLOW_PIN = 10;
const int GREEN_PIN = 11;
void setup() {
pinMode(RED_PIN, OUTPUT);
pinMode(YELLOW_PIN, OUTPUT);
pinMode(GREEN_PIN, OUTPUT);
}
void loop() {
}That's the skeleton. setup() declares all three pins as outputs. loop() is empty — we'll fill it in once we've tested that the wiring is right.
Why it matters
The "many components, shared rails" pattern is the entire grammar of breadboarding. Every project from here on — traffic lights, RGB nightlights, environmental sensors, robots — uses the same idea: separate signal wires for each part, shared power and ground via the rails.
Worked Example 20 min
Goal: build the three-LED breadboard layout and verify every LED works with a simple "all on" test sketch — before writing any animation logic.
The full wiring diagram
GND pin. Adding a fourth LED tomorrow would mean adding only a fourth column-pair + one more drop into the − rail — the GND wire to the Arduino stays exactly the same.The "wiring test" sketch
Before writing animation logic, prove the wiring is right. This sketch turns on all three LEDs in setup() and then sits in an empty loop() doing nothing — the LEDs stay on as long as the board has power.
const int RED_PIN = 9;
const int YELLOW_PIN = 10;
const int GREEN_PIN = 11;
void setup() {
pinMode(RED_PIN, OUTPUT);
pinMode(YELLOW_PIN, OUTPUT);
pinMode(GREEN_PIN, OUTPUT);
digitalWrite(RED_PIN, HIGH);
digitalWrite(YELLOW_PIN, HIGH);
digitalWrite(GREEN_PIN, HIGH);
}
void loop() {
}Expected behaviour
- All three LEDs come on the instant the board boots, and stay on.
- If any of the three is dark, you have a wiring problem on that module alone. Flip its LED first (polarity is the most common culprit), then check its resistor, then check the column numbers against the wiring table.
- The
loop()body is empty on purpose. We haven't told the Arduino to do anything over and over yet — that's the next step.
Try It Yourself 20 min
Three sketches that build on the wiring test. For each one, predict on paper what the LEDs will do, then upload and check.
Goal: Light only the green LED. Leave red and yellow off. Confirm you can switch a single LED on its own without affecting the others.
const int RED_PIN = 9;
const int YELLOW_PIN = 10;
const int GREEN_PIN = 11;
void setup() {
pinMode(RED_PIN, OUTPUT);
pinMode(YELLOW_PIN, OUTPUT);
pinMode(GREEN_PIN, OUTPUT);
digitalWrite(GREEN_PIN, HIGH);
}
void loop() {
}Question: Why don't you need digitalWrite(RED_PIN, LOW) and digitalWrite(YELLOW_PIN, LOW) in this sketch? ____ (Hint: what's the default state of a pin after pinMode(pin, OUTPUT)?)
Goal: Make all three LEDs blink in sync — on together for 500 ms, off together for 500 ms.
const int RED_PIN = 9;
const int YELLOW_PIN = 10;
const int GREEN_PIN = 11;
void setup() {
pinMode(RED_PIN, OUTPUT);
pinMode(YELLOW_PIN, OUTPUT);
pinMode(GREEN_PIN, OUTPUT);
}
void loop() {
digitalWrite(RED_PIN, HIGH);
digitalWrite(YELLOW_PIN, HIGH);
digitalWrite(GREEN_PIN, HIGH);
delay(500);
digitalWrite(RED_PIN, LOW);
digitalWrite(YELLOW_PIN, LOW);
digitalWrite(GREEN_PIN, LOW);
delay(500);
}Notice: loop() is starting to feel repetitive — six digitalWrite lines for what is really one idea ("all on, then all off"). This is exactly the problem the for loop will solve in L01-11. For now, the long-hand version is fine.
Question: If a 4th LED was added on pin 12, how many lines would loop() grow by? ____
Goal: A "chase" — red lights up, then yellow takes over (red goes off), then green takes over (yellow goes off), then all off, repeating. Like a single dot moving across the three LEDs.
// Chase: one LED at a time, walking left to right.
const int RED_PIN = 9;
const int YELLOW_PIN = 10;
const int GREEN_PIN = 11;
void setup() {
pinMode(RED_PIN, OUTPUT);
pinMode(YELLOW_PIN, OUTPUT);
pinMode(GREEN_PIN, OUTPUT);
}
void loop() {
digitalWrite(RED_PIN, HIGH);
delay(200);
digitalWrite(RED_PIN, LOW);
digitalWrite(YELLOW_PIN, HIGH);
delay(200);
digitalWrite(YELLOW_PIN, LOW);
digitalWrite(GREEN_PIN, HIGH);
delay(200);
digitalWrite(GREEN_PIN, LOW);
}Questions:
- What happens if you remove the three
delay(200)lines — does the chase still work? Why or why not? ____ - What single change to the code would make the dot "walk" from green to yellow to red (right to left) instead? ____
Mini-Challenge 15 min
The "bounce"
Combine the chase pattern (🔴 stretch) with a reversed pass so the dot bounces: red → yellow → green → yellow → red → yellow → green → yellow → red → … The dot walks right across the LEDs, then walks back left, and repeats forever.
Your task:
- Start from the chase sketch in the 🔴 task.
- Add a "return journey" inside
loop()— yellow on, then yellow off + red on. The cycle ends back on red, ready for the next loop iteration. - Pick a step delay that makes the bounce look smooth but not frantic. 150 ms is a good starting point.
- Upload and watch. The bouncing dot is one of the most recognisable patterns in electronics — Knight Rider, KITT's grille, the 1980s called.
It works if:
- At any instant, exactly one LED is on. Never zero, never two.
- The dot reaches the green LED, pauses (one step), then walks back through yellow to red, pauses, then walks forward again.
- A partner watching the breadboard can describe the pattern as "bouncing" without you explaining it first.
Reveal one valid sketch
// Knight Rider bounce — red → yellow → green → yellow → red, repeating.
const int RED_PIN = 9;
const int YELLOW_PIN = 10;
const int GREEN_PIN = 11;
const int STEP_MS = 150;
void setup() {
pinMode(RED_PIN, OUTPUT);
pinMode(YELLOW_PIN, OUTPUT);
pinMode(GREEN_PIN, OUTPUT);
}
void loop() {
digitalWrite(RED_PIN, HIGH); delay(STEP_MS); digitalWrite(RED_PIN, LOW);
digitalWrite(YELLOW_PIN, HIGH); delay(STEP_MS); digitalWrite(YELLOW_PIN, LOW);
digitalWrite(GREEN_PIN, HIGH); delay(STEP_MS); digitalWrite(GREEN_PIN, LOW);
digitalWrite(YELLOW_PIN, HIGH); delay(STEP_MS); digitalWrite(YELLOW_PIN, LOW);
}Yes, the loop body is dense — three statements pressed onto one line per step. We'll allow it only because the for loop in L01-11 is one lesson away and will rewrite this in four lines. The bounce pattern itself, four steps × one LED each, is what matters today.
Recap 5 min
To drive N independent LEDs you need N Arduino pins, N resistors and N LEDs — but only one GND path, gathered through the breadboard's − rail. Give every pin a colour-named constant at the top of the sketch and you can read the logic of loop() in plain English. The longhand digitalWrite calls are getting repetitive — that is your sneak preview of why for loops exist.
- Module
- One LED + its current-limiting resistor + the wires that join them. A self-contained sub-circuit on the breadboard. Today's circuit has three modules.
- GND bus
- A shared wire — usually a breadboard power rail — that gathers GND returns from several components and carries them back to the Arduino's
GNDpin as one. The − rail's job in today's circuit. - Chase
- An animation in which one LED at a time is lit, marching across a row of LEDs. The simplest multi-LED effect.
- Independence
- The property that switching one LED on or off has no effect on the others, because each is on its own pin and resistor. Today's circuit guarantees it; cheap toy circuits that share resistors don't.
Homework 5 min
Design a 3-LED panic signal. Write a sketch where, every full cycle:
- All three LEDs blink together rapidly — 5 quick flashes (80 ms on, 80 ms off).
- Then all three stay off for 2 seconds.
- Then the cycle repeats.
Use the three named pin constants from class. The sketch will run longer than 10 lines — that's OK for homework; the lesson in L01-11 is exactly about making patterns like this shorter.
Also: do the quick safety check from L01-05 + L01-07 — when all three LEDs are simultaneously HIGH, what is the total current the Arduino is supplying through pins D9 + D10 + D11 together?
- Given: each module:
V_pin = 5 V,V_F (LED) ≈ 2 V,R = 220 Ω - Per-module current:
I = (5 − 2) ÷ 220 = ____ mA - Total when all three are HIGH:
3 × ____ mA = ____ mA - The Arduino UNO can supply about 200 mA total across all its pins safely. Is your three-LED circuit comfortably under this budget?
Bring back next class:
- The saved
.inofile (call itthree-led-panic). - A short phone video (10–15 seconds) showing the panic pattern in action.
- Your notebook page with the per-module and total current figures.