Menu
CoddyTech

行人信号灯和蜂鸣器

本课属于 Coddy Arduino 学习旅程的“项目”单元。第 4 课,共 24 课。

行人有自己的信号灯:红灯接在引脚 7 上(等待),绿灯接在引脚 6 上(通行)。汽车亮红灯时,行人看到绿灯;其余时间,行人看到红灯。

行人信号只在两个时刻切换:汽车信号灯变红时,以及红灯结束时。为行人信号灯编写一个函数,并在这两个位置调用它:

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

在可以安全过马路时,斑马线信号灯还会发出哔声,为看不到信号灯的人提供提示。tone() 可以接收第三个数字,表示播放时长:tone(buzzerPin, 1000, 100) 会以 1000 Hz 的频率播放 100 ms,然后自动停止。程序不会等待它播放完。

要只在红灯期间每隔 500 ms 发出一次哔声,请在 case RED: 中添加第三个 millis() 计时器。

challenge icon

挑战

中等

添加行人信号灯和蜂鸣器:

  • 行人红灯接在引脚 7 上,行人绿灯接在引脚 6 上,两者都设为输出
  • 汽车信号灯为红灯时:行人绿灯亮,行人红灯灭,并且每隔 500 ms 在引脚 8 上以 1000 Hz 蜂鸣 100 ms
  • 其余时间:行人红灯亮,行人绿灯灭,不发出声音

按“运行”,然后按“检查”。

亲手试试

// 车辆信号灯
const int redPin = 12;
const int yellowPin = 11;
const int greenPin = 10;
// 开发板自带的 LED:控制器的状态灯
const int statusPin = 13;
// 过街按钮
const int buttonPin = 2;

enum Light { GREEN, YELLOW, RED };
Light light = GREEN;
unsigned long lightStart = 0;  // 当前信号灯亮起的时间

bool statusOn = false;
unsigned long lastBlink = 0;

// 打开一盏灯,关闭另外两盏。
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:
      // 按下过街按钮会让绿灯提前结束。
      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;
  }

  // 无论车辆信号灯如何变化,状态灯每隔 500 ms 闪烁一次。
  if (now - lastBlink >= 500) {
    lastBlink = now;
    if (statusOn) {
      statusOn = false;
      digitalWrite(statusPin, LOW);
    } else {
      statusOn = true;
      digitalWrite(statusPin, HIGH);
    }
  }
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

项目中的所有课

自己练习: Arduino 在线编辑器