Menu
CoddyTech

Walk Signal and Beeper

Part of the Projects section of Coddy's Arduino journey. Lesson 4 of 24.

People on foot get their own lights: red on pin 7 (wait) and green on pin 6 (walk). While the cars have red, people see green; the rest of the time they see red.

The walk signal changes at only two moments: when the cars enter red and when they leave it. Write a function for the walk lights and call it in those two places:

void showWalk(bool walk) {
  if (walk) {
    digitalWrite(walkRedPin, LOW);
    digitalWrite(walkGreenPin, HIGH);
  } else {
    digitalWrite(walkGreenPin, LOW);
    digitalWrite(walkRedPin, HIGH);
  }
}

Crossings also beep while it is safe to cross, for people who cannot see the lights. tone() can take a third number, how long to play: tone(buzzerPin, 1000, 100) plays 1000 Hz for 100 ms and stops by itself. The sketch does not wait for it.

To beep every 500 ms during the red only, put a third millis() timer inside case RED:.

challenge icon

Challenge

Medium

Add the walk signal and its beeper:

  • walk red on pin 7 and walk green on pin 6, both outputs
  • while the cars have red: walk green on, walk red off, and a 100 ms beep at 1000 Hz on pin 8 every 500 ms
  • the rest of the time: walk red on, walk green off, no sound

Press Run, 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;
// The crossing button
const int buttonPin = 2;

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);
  pinMode(buttonPin, INPUT_PULLUP);
  showLight(greenPin);
}

void loop() {
  unsigned long now = millis();

  switch (light) {
    case GREEN:
      // A press on the crossing button ends the green early.
      if (now - lightStart >= 3000 || digitalRead(buttonPin) == LOW) {
        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);
    }
  }
}
quiz iconTest yourself

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