Crossing Button
Part of the Projects section of Coddy's Arduino journey. Lesson 3 of 24.
People on foot need a way to ask for the road. The blue button on pin 2 is the crossing button: a press during the green ends the green at once, so the cars get yellow, then red.
Because the lights run on millis(), loop() passes the green state thousands of times a second and can read the button each time, as well as the clock. The green ends when either is true, which is what || (or) says:
case GREEN:
if (millis() - lightStart >= 3000 || digitalRead(buttonPin) == LOW) {
// change to yellow
}
break;The button joins pin 2 to ground, so set the pin to INPUT_PULLUP: it reads HIGH until the button pulls it LOW.
Only the green state reads the button. In the yellow and the red the cars are already stopping, and the yellow keeps its full second so drivers have time to stop.
Challenge
MediumAdd the crossing button on pin 2:
- set pin 2 to
INPUT_PULLUP - while the light is green, a press ends the green at once (the light turns yellow)
- yellow and red keep their times, pressed or not
Press Run, wait for the green, press the blue button, then Check.
Try it yourself
// The car lights
const int redPin = 12;
const int yellowPin = 11;
const int greenPin = 10;
// The board's own LED: the controller's status light
const int statusPin = 13;
enum Light { GREEN, YELLOW, RED };
Light light = GREEN;
unsigned long lightStart = 0; // when the current light came on
bool statusOn = false;
unsigned long lastBlink = 0;
// 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);
pinMode(statusPin, OUTPUT);
showLight(greenPin);
}
void loop() {
unsigned long now = millis();
switch (light) {
case GREEN:
if (now - lightStart >= 3000) {
light = YELLOW;
lightStart = now;
showLight(yellowPin);
}
break;
case YELLOW:
if (now - lightStart >= 1000) {
light = RED;
lightStart = now;
showLight(redPin);
}
break;
case RED:
if (now - lightStart >= 3000) {
light = GREEN;
lightStart = now;
showLight(greenPin);
}
break;
}
// The status light blinks every 500 ms, whatever the car lights do.
if (now - lastBlink >= 500) {
lastBlink = now;
if (statusOn) {
statusOn = false;
digitalWrite(statusPin, LOW);
} else {
statusOn = true;
digitalWrite(statusPin, HIGH);
}
}
}
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