← All projects
Basics Beginner

ESP32 Traffic Light: Three LEDs and a Sequence of States

A classic learning project: red, yellow and green LEDs with resistors and a traffic-light cycle with a blinking green. We learn to move repeated code into a function and plan a sequence of states.

Difficulty
Beginner
Time
30 min
Category
Basics
Updated

About the project

A traffic light is the perfect exercise in driving several outputs at once: three LEDs, a clear sequence of states and timings. Along the way we learn not to repeat three digitalWrite() calls on every line.

What you need

  • ESP32 DevKit
  • LEDs: red, yellow, green
  • 3 × 220 Ω resistors
  • Breadboard and jumper wires

Wiring

Colour GPIO Circuit
Red GPIO25 GPIO → 220 Ω → anode; cathode → GND
Yellow GPIO26 same
Green GPIO27 same

Every LED gets its own resistor. One shared resistor on all the cathodes is a bad idea: the brightness would depend on how many LEDs are on, and the red one (lower voltage) would hog the current.

The sequence

The cycle, as on Ukrainian traffic lights:

Step Red Yellow Green Duration
Stop ● 3 s
Get ready ● ● 1 s
Go ● 3 s
Green blinks ◐ ×3 ~2 s
Caution ● 1 s

Each state is three on/off values, so one function set(r, y, g) sets them all.

Code

// Traffic light: red, yellow, green on GPIO25, 26, 27
const int RED = 25, YELLOW = 26, GREEN = 27;

// one traffic-light state — one function instead of three digitalWrite calls
void set(bool r, bool y, bool g) {
  digitalWrite(RED, r);
  digitalWrite(YELLOW, y);
  digitalWrite(GREEN, g);
}

void setup() {
  pinMode(RED, OUTPUT);
  pinMode(YELLOW, OUTPUT);
  pinMode(GREEN, OUTPUT);
}

void loop() {
  set(1, 0, 0); delay(3000);   // stop
  set(1, 1, 0); delay(1000);   // get ready
  set(0, 0, 1); delay(3000);   // go
  for (int i = 0; i < 3; i++) { set(0, 0, 0); delay(300); set(0, 0, 1); delay(300); }   // green blinks
  set(0, 1, 0); delay(1000);   // caution
}

Taking it further

  • Pedestrian button. Right now delay() blocks everything, so a button would not respond mid-cycle. Rewrite the light as a state machine: a state variable and the time you entered it, stateSince = millis(). In loop(), check whether it is time to move on, and poll the button at the same time.
  • Night mode. Blink yellow when a photoresistor sees darkness.
  • Crossroads. A second set of LEDs runs in opposite phase to the first.

Good to know

GPIO25–27 are convenient outputs: they take no part in booting and are not used by the flash. For outputs avoid GPIO6–11 (flash) and GPIO34–39 (input-only).