Traffic Light on millis()
Part of the Projects section of Coddy's Arduino journey. Lesson 2 of 24.
During each delay(3000) the board does nothing else, so it could not notice the crossing button the next step adds. The timing moves to millis().
The light is a state machine: it is always in one state (green, yellow or red) and moves to the next when that state has lasted long enough. An enum names the states, one variable holds the current state, and another holds when it started:
enum Light { GREEN, YELLOW, RED };
Light light = GREEN;
unsigned long lightStart = 0;The first state is green, so light the green in setup(). On every pass of loop(), a switch asks the current state if it has lasted long enough, and only then moves on and changes the lights:
case GREEN:
if (millis() - lightStart >= 3000) {
light = YELLOW;
lightStart = millis();
showLight(yellowPin);
}
break;Nothing waits, so loop() is free for other jobs. Prove it with a status light: blink the board's own LED, pin 13, every 500 ms.
Challenge
MediumRewrite the timing without delay():
- keep green 3000 ms, yellow 1000 ms, red 3000 ms
- use an
enumfor the three states, aswitch, andmillis() - light the green in
setup(), and callshowLight()only when the state changes - blink pin 13 every 500 ms (500 ms on, 500 ms off), all the time
Press Run, then Check.
Try it yourself
// The car lights
const int redPin = 12;
const int yellowPin = 11;
const int greenPin = 10;
// Turn on one light and the other two off.
void showLight(int pin) {
digitalWrite(redPin, LOW);
digitalWrite(yellowPin, LOW);
digitalWrite(greenPin, LOW);
digitalWrite(pin, HIGH);
}
void setup() {
pinMode(redPin, OUTPUT);
pinMode(yellowPin, OUTPUT);
pinMode(greenPin, OUTPUT);
}
void loop() {
showLight(greenPin);
delay(3000);
showLight(yellowPin);
delay(1000);
showLight(redPin);
delay(3000);
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Projects
Practice on your own: Arduino playground