Traffic light state machine on Arduino
Six LEDs, two buttons, four states, no delay(). A two-direction traffic light where a timer or a button press moves the system on, and the code is one switch statement.

Two directions of traffic, north–south and east–west. Each gets a red, a yellow and a green LED. Every ten seconds the green side goes yellow, then red, and the other side goes green. Two buttons stand in for a car sensor or a pedestrian button: press one and its direction gets green early. The whole thing is a finite state machine with four states.
The hardware
- Six LEDs through 1 kΩ resistors from pins 13, 12, 11 (north–south green, yellow, red) and 10, 9, 8 (east–west green, yellow, red). All cathodes to the ground rail.
- Two pushbuttons on pins 7 and 6, using the internal pull-up, so a press reads LOW.
Lay it out so you can read it. Straighten resistor legs and put them in the same rows every time. Bend the long (positive) LED leg into a hook so polarity is visible at a glance. When something does not light, you want to rule out polarity in a second, not a minute.

The four states
| State | North–south | East–west | Leaves on |
|---|---|---|---|
| 0 | green | red | 10 s, or the east–west button |
| 1 | yellow | red | 1 s |
| 2 | red | green | 10 s, or the north–south button |
| 3 | red | yellow | 1 s |
Yellow states only exit on the timer. A button press cannot skip a yellow; that is the point of yellow.
The code
The important decision is no delay(). A delay would block the loop, and a button pressed during the wait would be missed. Instead the loop runs continuously and compares millis() with the time of the last state change.

At the top: pin numbers, greenTime = 10000 and yellowTime = 1000 as unsigned long, lastChange, state, and two boolean flags for the buttons.
setup() opens the serial port, sets the LED pins as outputs, the button pins as INPUT_PULLUP, writes the starting lights, and records lastChange = millis().
loop():
currentTime = millis().- Read each button. If it reads LOW, set its flag and print a line to serial so you can see it happen.
switch (state). Each case prints its name, then checkscurrentTime - lastChange >= greenTime(oryellowTime) or, in the green states, the relevant button flag. If so: write the new LED pattern, set the nextstate, setlastChange = currentTime, clear the button flag.

Case 3 goes back to state 0. In the video I had typed 4 there by mistake; there is no state 4, and the lights would have frozen. Serial prints are how you catch that kind of thing.