Traffic light on an Arduino Uno
An Uno runs a pelican crossing, with a 74HC04 lighting the WAIT lamp straight off the button. The whole build, an Arduino Uno and 12 more parts, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.
IntermediateRuns in your browser. Free, and no account needed.
Step by step, with the wiring and the common mistakes: Arduino Traffic Light with a Crossing Button
The code
The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.
// Traffic light: a pelican crossing with a button that actually does
// something.
//
// pin 8 red pin 11 walk
// pin 9 amber pin 2 request button, to GND, internal pull-up
// pin 10 green
//
// The button is on INT0, so a press is caught by the interrupt even while
// loop() is asleep inside delay(). Without that the sketch would only notice a
// press if you happened to be holding the button when it got round to looking,
// which is exactly the bug every first crossing sketch has.
//
// Green is the resting state and it waits there for a request, but never for
// less than MIN_GREEN: a crossing that stopped the traffic the instant anyone
// asked would never let a car through.
//
// The WAIT lamp on the breadboard is not driven from here at all. It hangs off
// a 74HC04 inverter wired straight to the button line, so it lights the moment
// the contact closes, a reminder that not everything has to be the
// microcontroller's job.
const int RED = 8;
const int AMBER = 9;
const int GREEN = 10;
const int WALK = 11;
const int BUTTON = 2;
const unsigned long MIN_GREEN = 3000;
const unsigned long MAX_GREEN = 9000;
const unsigned long AMBER_MS = 1500;
const unsigned long WALK_MS = 4000;
volatile bool requested = false;
static void onPress() { requested = true; }
static void lights(int red, int amber, int green) {
digitalWrite(RED, red ? HIGH : LOW);
digitalWrite(AMBER, amber ? HIGH : LOW);
digitalWrite(GREEN, green ? HIGH : LOW);
}
// Hold green until someone asks, or until the maximum runs out.
static void waitForRequest() {
unsigned long started = millis();
for (;;) {
unsigned long waited = millis() - started;
if (waited >= MAX_GREEN) return;
noInterrupts();
bool asked = requested;
interrupts();
if (asked && waited >= MIN_GREEN) return;
delay(20);
}
}
void setup() {
pinMode(RED, OUTPUT);
pinMode(AMBER, OUTPUT);
pinMode(GREEN, OUTPUT);
pinMode(WALK, OUTPUT);
pinMode(BUTTON, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(BUTTON), onPress, FALLING);
Serial.begin(115200);
Serial.println("Mokxi Arduino Uno: crossing ready, press the button");
}
void loop() {
lights(0, 0, 1);
Serial.println("green");
waitForRequest();
lights(0, 1, 0);
Serial.println("amber");
delay(AMBER_MS);
lights(1, 0, 0);
digitalWrite(WALK, HIGH);
Serial.println("walk");
delay(WALK_MS);
// the flashing period at the end of the walk phase
// The pelican's own ending: the walk lamp flashes to say "finish crossing"
// while the drivers get a flashing amber, which means "go if the crossing
// is clear". Then straight back to green. (A red-and-amber pair before
// green is the junction signal's sequence, not a crossing's.)
Serial.println("flashing amber");
for (int i = 0; i < 12; i++) {
int on = (i & 1) ? LOW : HIGH;
digitalWrite(WALK, on);
lights(0, on == HIGH, 0);
delay(500);
}
digitalWrite(WALK, LOW);
noInterrupts();
requested = false;
interrupts();
}
Parts list
14 parts, plus the jumper wires. Every one is in the editor's parts bin.
- 1 × Arduino Uno R3
- 1 × Full-size breadboard
- 1 × 74HC04 hex inverter
- 1 × Pushbutton
- 5 × Resistor, 220 Ω
- 1 × LED, red
- 1 × LED, yellow
- 1 × LED, green
- 1 × LED, white
- 1 × LED, blue
How it is wired
13 connections, pin by pin, read from the circuit itself. Each line is one set of pins joined together, by a jumper wire or a breadboard strip.
- Ground: Arduino Uno R3 pin GND; 74HC04 hex inverter pin GND; Pushbutton pin 2a; LED, red pin C; LED, yellow pin C; LED, green pin C; LED, white pin C; LED, blue pin C
- Arduino Uno R3 pin 11; Resistor, 220 Ω (4) pin 1
- Arduino Uno R3 pin 10; Resistor, 220 Ω (3) pin 1
- Arduino Uno R3 pin 9; Resistor, 220 Ω (2) pin 1
- Arduino Uno R3 pin 8; Resistor, 220 Ω (1) pin 1
- Arduino Uno R3 pin 2; 74HC04 hex inverter pin 1A; Pushbutton pin 1a
- Arduino Uno R3 pin 5V; 74HC04 hex inverter pin VCC
- 74HC04 hex inverter pin 1Y; Resistor, 220 Ω (5) pin 1
- Resistor, 220 Ω (1) pin 2; LED, red pin A
- Resistor, 220 Ω (2) pin 2; LED, yellow pin A
- Resistor, 220 Ω (3) pin 2; LED, green pin A
- Resistor, 220 Ω (4) pin 2; LED, white pin A
- Resistor, 220 Ω (5) pin 2; LED, blue pin A
Change it and keep it
Open it in the editor, change the circuit or the code, and keep your version in a free account.