过街按钮
本课属于 Coddy Arduino 学习旅程的“项目”单元。第 3 课,共 24 课。
行人需要一种请求通行的方式。引脚 2 上的蓝色按钮就是过街按钮:在绿灯期间按下按钮,绿灯会立即结束,然后汽车会遇到黄灯,再接着是红灯。
由于灯光通过 millis() 运行,loop() 每秒会多次经过绿灯状态,并且每次都能读取按钮和时钟。如果其中一个条件成立,绿灯就会结束,这正是 ||(或)的含义:
case GREEN:
if (millis() - lightStart >= 3000 || digitalRead(buttonPin) == LOW) {
// 切换为黄灯
}
break;按钮会将引脚 2 与接地端连接,因此要将引脚设置为 INPUT_PULLUP:在按钮将其拉低为 LOW 之前,它会读取为 HIGH。
只有绿灯状态会读取按钮。在黄灯和红灯状态下,汽车已经在停车,而黄灯会持续完整的一秒,让驾驶员有时间停车。
挑战
中等在引脚 2 上添加行人过街按钮:
- 将引脚 2 设置为
INPUT_PULLUP - 绿灯亮起时,按下按钮会立即结束绿灯(灯变为黄灯)
- 无论是否按下按钮,黄灯和红灯的持续时间都不变
点击运行,等待绿灯亮起,按下蓝色按钮,然后点击检查。
亲手试试
// 汽车信号灯
const int redPin = 12;
const int yellowPin = 11;
const int greenPin = 10;
// 开发板自带的 LED:控制器的状态灯
const int statusPin = 13;
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);
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;
}
// 无论汽车信号灯如何变化,状态灯每隔 500 ms 闪烁一次。
if (now - lastBlink >= 500) {
lastBlink = now;
if (statusOn) {
statusOn = false;
digitalWrite(statusPin, LOW);
} else {
statusOn = true;
digitalWrite(statusPin, HIGH);
}
}
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
项目中的所有课
自己练习: Arduino 在线编辑器