Multiple LED Patterns (Traffic Light) Using Arduino Uno in Wokwi – Step-by-Step Guide

Multiple LED Patterns (Traffic Light) using Arduino Uno | MakeMindz
🚦 Lesson 2 · LED Output & Logic

Multiple LED Patterns
(Traffic Light) using Arduino Uno

Build a complete traffic light system with 5 real-world modes — pedestrian crossing, emergency alerts, night mode and more. One button controls everything!

🟢 Beginner ⚡ Arduino Uno 💡 5 LEDs 🔘 Push Button 🚦 5 Modes ⏱ 30 min
Run Free Simulation on Wokwi

🚦 Project Overview

This project simulates a real traffic intersection with vehicle and pedestrian signals. A single push button cycles between 5 operating modes, each teaching a different programming concept.

💡

Real-world connection: Every traffic light you see at a road intersection uses the exact same logic as this project — digital outputs, timed sequences, and mode-based state switching!

Vehicle
Signal
Green — GO5s
Yellow — SLOW2s
Red — STOP5s

🛒 Components Required

🟦
Arduino Uno
× 1
Red LED
× 2
Yellow LED
× 1
Green LED
× 2
🟫
220Ω Resistors
× 5
🔘
Push Button
× 1
🔌
Jumper Wires
× 12+

🌐

No hardware? Open the free Wokwi simulation — all 5 LEDs, the button, and resistors are already placed and wired for you!

🔧 Circuit Connections

Vehicle Traffic LEDs

LED ColorArduino PinVia Resistor
RedPin 13220Ω
YellowPin 12220Ω
GreenPin 11220Ω

Pedestrian LEDs

LEDArduino PinVia Resistor
Pedestrian RedPin 10220Ω
Pedestrian GreenPin 9220Ω

Push Button

Button LegConnection
One sidePin 2
Other sideGND
ModeINPUT_PULLUP (no resistor needed)
RULE 1
Always use 220Ω resistors with LEDs

Connect each LED's anode (+, longer leg) through a 220Ω resistor to the Arduino pin. The cathode (−, shorter leg) goes directly to GND. Without resistors, too much current flows and the LED burns out instantly.

RULE 2
INPUT_PULLUP means no external resistor needed

The button uses INPUT_PULLUP mode — this activates an internal 20kΩ resistor inside the Arduino, keeping Pin 2 HIGH. When the button is pressed it connects to GND, pulling Pin 2 LOW.

🗺️ Wokwi Diagram.json

Paste this into the diagram.json tab in your Wokwi project to instantly get the complete circuit with all 5 LEDs, resistors, and button placed and wired.

💡

How to use: Open Wokwi → New Project → Arduino Uno → click the diagram.json tab → Select All (Ctrl+A) → paste → Ctrl+S. The full circuit appears instantly!

DIAGRAM.JSON · WOKWI
{
  "version": 1,
  "author": "MakeMindz",
  "editor": "wokwi",
  "parts": [
    { "type": "wokwi-arduino-uno", "id": "uno", "top": 0, "left": 0, "attrs": {} },
    { "type": "wokwi-led", "id": "led-red", "top": -120, "left": 250, "attrs": { "color": "red" } },
    { "type": "wokwi-led", "id": "led-yellow", "top": -60, "left": 250, "attrs": { "color": "yellow" } },
    { "type": "wokwi-led", "id": "led-green", "top": 0, "left": 250, "attrs": { "color": "green" } },
    { "type": "wokwi-led", "id": "led-ped-red", "top": 80, "left": 250, "attrs": { "color": "red" } },
    { "type": "wokwi-led", "id": "led-ped-green", "top": 140, "left": 250, "attrs": { "color": "green" } },
    { "type": "wokwi-resistor", "id": "r1", "top": -110, "left": 180, "attrs": { "value": "220" } },
    { "type": "wokwi-resistor", "id": "r2", "top": -50, "left": 180, "attrs": { "value": "220" } },
    { "type": "wokwi-resistor", "id": "r3", "top": 10, "left": 180, "attrs": { "value": "220" } },
    { "type": "wokwi-resistor", "id": "r4", "top": 90, "left": 180, "attrs": { "value": "220" } },
    { "type": "wokwi-resistor", "id": "r5", "top": 150, "left": 180, "attrs": { "value": "220" } },
    { "type": "wokwi-pushbutton", "id": "btn1", "top": 220, "left": 50, "attrs": { "color": "blue" } }
  ],
  "connections": [
    [ "uno:13", "r1:1", "green", ["v0"] ],
    [ "r1:2", "led-red:A", "green", ["v0"] ],
    [ "led-red:C", "uno:GND.1", "black", ["v0"] ],

    [ "uno:12", "r2:1", "yellow", ["v0"] ],
    [ "r2:2", "led-yellow:A", "yellow", ["v0"] ],
    [ "led-yellow:C", "uno:GND.1", "black", ["v0"] ],

    [ "uno:11", "r3:1", "green", ["v0"] ],
    [ "r3:2", "led-green:A", "green", ["v0"] ],
    [ "led-green:C", "uno:GND.1", "black", ["v0"] ],

    [ "uno:10", "r4:1", "red", ["v0"] ],
    [ "r4:2", "led-ped-red:A", "red", ["v0"] ],
    [ "led-ped-red:C", "uno:GND.2", "black", ["v0"] ],

    [ "uno:9", "r5:1", "green", ["v0"] ],
    [ "r5:2", "led-ped-green:A", "green", ["v0"] ],
    [ "led-ped-green:C", "uno:GND.2", "black", ["v0"] ],

    [ "btn1:1.l", "uno:2", "blue", ["v0"] ],
    [ "btn1:2.r", "uno:GND.3", "black", ["v0"] ]
  ],
  "dependencies": {}
}
⚠️

Copy the entire JSON including the outer { } braces, or the circuit won't load. Use Ctrl+A to select all before pasting.

What Each Connection Does

uno:13 → r1 → led-red:A

Pin 13 → 220Ω resistor → Red LED anode. The resistor limits current to a safe ~14mA

led-red:C → GND

LED cathode (short leg) returns to ground, completing the circuit when Pin 13 is HIGH

btn1:1.l → uno:2

Button input to Pin 2. INPUT_PULLUP holds it HIGH until button press pulls it LOW

btn1:2.r → GND

Button other leg to GND — pressing bridges Pin 2 to GND, triggering LOW reading

🚦 5 Traffic Light Modes

Press the blue button to cycle through all 5 modes. Each mode is a different real-world traffic scenario.

MODE 0
🚦
Standard Traffic
Green→Yellow→Red cycle
MODE 1
🚶
Pedestrian Crossing
With blinking warning
MODE 2
🚨
Emergency Mode
All red LEDs blink
MODE 3
🌙
Night Mode
Blinking yellow only
MODE 4
Pattern Demo
Chase, blink, alternating

Mode 0 — Standard Traffic Light

Green ON → Pedestrian Red ON5 sec
Yellow ON (caution)2 sec
Red ON → repeat5 sec

Mode 1 — Pedestrian Crossing

Vehicles Green → Pedestrians Red STOP4 sec
Vehicles Yellow → Pedestrians wait2 sec
Vehicles Red → Pedestrians Green WALK5 sec
Pedestrian green blinks (finish crossing!)3 sec

🎮 Try It Live — No Hardware Needed!

Click the blue button in the Wokwi simulation to switch between all 5 modes and watch the LEDs respond in real time.

Open Wokwi Simulation

🔍 How the Code Works

pinMode(pin, OUTPUT)

Configures an LED pin as an output — tells Arduino this pin will SEND signals, not receive them

digitalWrite(pin, HIGH)

Sends 5V to the pin → LED turns ON. Use LOW to set 0V → LED turns OFF

INPUT_PULLUP

Button mode that uses Arduino's internal resistor — no external resistor needed. Button reads HIGH when open, LOW when pressed

delay(5000)

Pauses the program for 5000 milliseconds (5 seconds) — controls how long each light stays on

millis() debouncing

Prevents a single button press registering multiple times — waits 50ms for the signal to stabilise before accepting input

switch(mode) { case 0: }

State machine — runs a different function depending on the current mode number (0–4)

💻 Full Arduino Code

Copy the complete code below and paste it into the sketch.ino tab in Wokwi. No libraries needed — all functions are built into Arduino!

ARDUINO · C++
/*
 * Multiple LED Patterns - Traffic Light System
 * MakeMindz Summer Class | makemindz.com
 * Simulation: https://wokwi.com/projects/459617287685848065
 * Modes: Standard | Pedestrian | Emergency | Night | Demo
 */

// ── Pin Definitions ───────────────────────────
const int redLED      = 13;  // Vehicle Red
const int yellowLED   = 12;  // Vehicle Yellow
const int greenLED    = 11;  // Vehicle Green
const int pedRedLED   = 10;  // Pedestrian Red
const int pedGreenLED = 9;   // Pedestrian Green
const int buttonPin   = 2;   // Mode button

// ── State Variables ───────────────────────────
int mode = 0;
int lastButtonState = HIGH;
int buttonState;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay    = 50;

void setup() {
  pinMode(redLED,      OUTPUT);
  pinMode(yellowLED,   OUTPUT);
  pinMode(greenLED,    OUTPUT);
  pinMode(pedRedLED,   OUTPUT);
  pinMode(pedGreenLED, OUTPUT);
  pinMode(buttonPin,   INPUT_PULLUP);

  Serial.begin(9600);
  Serial.println("Traffic Light System Ready!");
  Serial.println("Press button to cycle modes 0-4");
  allOff();
}

void loop() {
  // ── Debounced button reading ──────────────
  int reading = digitalRead(buttonPin);

  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (reading != buttonState) {
      buttonState = reading;
      if (buttonState == LOW) {    // Button pressed
        mode++;
        if (mode > 4) mode = 0;
        Serial.print("Mode: ");
        Serial.println(mode);
        allOff();
        delay(500);
      }
    }
  }
  lastButtonState = reading;

  // ── Run current mode ──────────────────────
  switch(mode) {
    case 0: standardTrafficLight(); break;
    case 1: pedestrianCrossing();   break;
    case 2: emergencyMode();        break;
    case 3: nightMode();             break;
    case 4: allPatternsDemo();      break;
  }
}

// ── MODE 0: Standard Traffic Light ────────────
void standardTrafficLight() {
  Serial.println("GREEN - GO");
  digitalWrite(greenLED,    HIGH);
  digitalWrite(yellowLED,   LOW);
  digitalWrite(redLED,      LOW);
  digitalWrite(pedRedLED,   HIGH);
  digitalWrite(pedGreenLED, LOW);
  delay(5000);

  Serial.println("YELLOW - CAUTION");
  digitalWrite(greenLED,  LOW);
  digitalWrite(yellowLED, HIGH);
  delay(2000);

  Serial.println("RED - STOP");
  digitalWrite(yellowLED, LOW);
  digitalWrite(redLED,    HIGH);
  delay(5000);
}

// ── MODE 1: Pedestrian Crossing ───────────────
void pedestrianCrossing() {
  // Vehicles GO, pedestrians STOP
  digitalWrite(greenLED,    HIGH);
  digitalWrite(yellowLED,   LOW);
  digitalWrite(redLED,      LOW);
  digitalWrite(pedRedLED,   HIGH);
  digitalWrite(pedGreenLED, LOW);
  delay(4000);

  // Transition
  digitalWrite(greenLED,  LOW);
  digitalWrite(yellowLED, HIGH);
  delay(2000);

  // Vehicles STOP, pedestrians WALK
  digitalWrite(yellowLED,   LOW);
  digitalWrite(redLED,      HIGH);
  digitalWrite(pedRedLED,   LOW);
  digitalWrite(pedGreenLED, HIGH);
  delay(5000);

  // Pedestrian warning blink
  for (int i = 0; i < 5; i++) {
    digitalWrite(pedGreenLED, LOW);  delay(300);
    digitalWrite(pedGreenLED, HIGH); delay(300);
  }
  digitalWrite(pedGreenLED, LOW);
  digitalWrite(pedRedLED,   HIGH);
}

// ── MODE 2: Emergency Mode ────────────────────
void emergencyMode() {
  for (int i = 0; i < 3; i++) {
    digitalWrite(redLED,    HIGH);
    digitalWrite(pedRedLED, HIGH);
    delay(500);
    digitalWrite(redLED,    LOW);
    digitalWrite(pedRedLED, LOW);
    delay(500);
  }
}

// ── MODE 3: Night Mode ────────────────────────
void nightMode() {
  digitalWrite(yellowLED, HIGH); delay(1000);
  digitalWrite(yellowLED, LOW);  delay(1000);
}

// ── MODE 4: All Patterns Demo ─────────────────
void allPatternsDemo() {
  // Sequential chase
  for (int i = 0; i < 2; i++) {
    digitalWrite(redLED, HIGH);    delay(200); digitalWrite(redLED, LOW);
    digitalWrite(yellowLED, HIGH); delay(200); digitalWrite(yellowLED, LOW);
    digitalWrite(greenLED, HIGH);  delay(200); digitalWrite(greenLED, LOW);
    digitalWrite(pedGreenLED, HIGH); delay(200); digitalWrite(pedGreenLED, LOW);
    digitalWrite(pedRedLED, HIGH); delay(200); digitalWrite(pedRedLED, LOW);
  }

  // All blink together
  for (int i = 0; i < 3; i++) {
    digitalWrite(redLED, HIGH); digitalWrite(yellowLED, HIGH);
    digitalWrite(greenLED, HIGH); digitalWrite(pedRedLED, HIGH);
    digitalWrite(pedGreenLED, HIGH);
    delay(400);
    allOff();
    delay(400);
  }

  // Alternating pattern
  for (int i = 0; i < 3; i++) {
    digitalWrite(redLED, HIGH); digitalWrite(greenLED, HIGH); digitalWrite(pedRedLED, HIGH);
    delay(400);
    allOff();
    digitalWrite(yellowLED, HIGH); digitalWrite(pedGreenLED, HIGH);
    delay(400);
    allOff();
  }
}

// ── Helper: Turn all LEDs off ─────────────────
void allOff() {
  digitalWrite(redLED,      LOW);
  digitalWrite(yellowLED,   LOW);
  digitalWrite(greenLED,    LOW);
  digitalWrite(pedRedLED,   LOW);
  digitalWrite(pedGreenLED, LOW);
}

🎓 What You Learn

Digital output control
LED sequencing
Traffic timing logic
Button debouncing
State machines
INPUT_PULLUP mode
Modular functions
millis() timing

🚀 Real-World Applications

🏫
Science Exhibitions
🏙️
Smart City Models
🤖
Robotics Training
📡
IoT Prototyping
🛣️
Traffic Automation
🎓
Embedded Systems

Frequently Asked Questions

❌ No — resistors are essential. Without them, excess current flows through the LED and burns it out instantly. They also protect the Arduino's output pins from drawing too much current.
✅ Yes! Add a buzzer on another digital pin and call tone(buzzerPin, 1000, 200) inside the pedestrianCrossing() function when the walk signal is active. Great extension challenge!
✅ Yes — replace delay() with millis()-based timing. This makes the button always responsive. For now, delay() is fine for learning. The Parking Sensor project on MakeMindz teaches the non-blocking approach!
This is because delay() blocks the entire Arduino — it can't read the button while waiting. This is the main limitation of delay()-based code. Use millis() for projects where responsiveness matters.
Mechanical buttons make and break contact multiple times in milliseconds when pressed — "bouncing". Without debouncing, one press could skip multiple modes. We wait 50ms after the first change before accepting the input.

📚 Full MakeMindz Course Map

🎉 Conclusion

The Multiple LED Patterns Traffic Light project teaches you the most fundamental Arduino concepts — digital outputs, timing, button debouncing, and state machines — through a recognisable real-world system.

Once you master this, you're ready for the next step: adding an LCD display, a buzzer, or replacing delay() with non-blocking millis() timing. Try the simulation and experiment with the timings!

Comments

try for free