Freedom Sale
Independence Day Special — Unlock the AI Path 70% off our most popular AI course · Limited time offer
--Days
--Hrs
--Min
--Sec
Claim Your Discount
✦ Beginner ⏱ 25 min

🚦 Build a Smart Traffic Light with Arduino

🎯 What You'll Build

A traffic light controller with red, yellow, and green LEDs — plus a push button for pedestrian crossing mode with adjustable phase timings.

📋 What You'll Need

1

Basic traffic light sequence

Three LEDs cycle through a standard traffic light pattern.

const int RED    = 8;
const int YELLOW = 9;
const int GREEN  = 10;

const int RED_TIME    = 5000;  // 5 seconds
const int YELLOW_TIME = 2000;  // 2 seconds
const int GREEN_TIME  = 5000;  // 5 seconds

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

void setLight(int red, int yellow, int green) {
  digitalWrite(RED,    red);
  digitalWrite(YELLOW, yellow);
  digitalWrite(GREEN,  green);
}

void loop() {
  setLight(HIGH, LOW, LOW);   delay(RED_TIME);    // RED
  setLight(LOW, HIGH, LOW);   delay(YELLOW_TIME); // YELLOW
  setLight(LOW, LOW, HIGH);   delay(GREEN_TIME);  // GREEN
  setLight(LOW, HIGH, LOW);   delay(YELLOW_TIME); // YELLOW
}
2

Add a pedestrian crossing button

When the button is pressed, the light goes red early so pedestrians can cross safely.

const int BUTTON = 2;
const int RED    = 8;
const int YELLOW = 9;
const int GREEN  = 10;

volatile bool pedestrianRequest = false;

// Interrupt fires when button is pressed
void buttonPressed() {
  pedestrianRequest = true;
}

void setup() {
  Serial.begin(9600);
  pinMode(RED,    OUTPUT);
  pinMode(YELLOW, OUTPUT);
  pinMode(GREEN,  OUTPUT);
  pinMode(BUTTON, INPUT);   // Use a 10k pull-down resistor to GND

  // External interrupt on pin 2 (INT0)
  attachInterrupt(digitalPinToInterrupt(BUTTON), buttonPressed, RISING);
}

void setLight(int r, int y, int g) {
  digitalWrite(RED, r); digitalWrite(YELLOW, y); digitalWrite(GREEN, g);
}

void loop() {
  // GREEN phase — cut short if pedestrian pressed button
  setLight(LOW, LOW, HIGH);
  unsigned long start = millis();
  while (millis() - start < 5000) {
    if (pedestrianRequest) {
      Serial.println("Pedestrian crossing requested!");
      delay(1000);  // give traffic a 1-second warning
      break;
    }
    delay(100);
  }

  // YELLOW
  setLight(LOW, HIGH, LOW); delay(2000);

  // RED — pedestrians cross
  setLight(HIGH, LOW, LOW);
  if (pedestrianRequest) {
    Serial.println("Pedestrian crossing — 10 seconds");
    delay(10000);  // longer red for crossing
    pedestrianRequest = false;
  } else {
    delay(5000);
  }

  // YELLOW before GREEN
  setLight(LOW, HIGH, LOW); delay(2000);
}
💡 Tip: attachInterrupt() uses pin 2 (INT0) or pin 3 (INT1) on the Uno. The RISING argument means the interrupt fires when the button signal goes from LOW to HIGH. Always use a pull-down resistor on button pins to prevent floating readings.

🎉 You Did It!

You built a state machine — the most fundamental programming pattern in embedded systems. Traffic lights, vending machines, elevators, and washing machines all use the same concept: track the current state, respond to inputs, transition to the next state.

Found something wrong?

Spotted a bug, broken code, or something that doesn't look right? Tell us what's off and we'll fix it.