用 millis() 控制交通信号灯
本课属于 Coddy Arduino 学习旅程的“项目”单元。第 2 课,共 24 课。
每次执行 delay(3000) 时,开发板都不会做其他事,因此它无法检测下一步要添加的过街按钮。计时改用 millis()。
这个灯是一个状态机:它始终处于一种状态(绿色、黄色或红色),并在该状态持续足够长时间后切换到下一个状态。enum 用来命名这些状态,一个变量保存当前状态,另一个变量记录状态开始的时间:
enum Light { GREEN, YELLOW, RED };
Light light = GREEN;
unsigned long lightStart = 0;第一个状态是绿色,因此在 setup() 中点亮绿灯。在每次执行 loop() 时,switch 都会检查当前状态是否持续了足够长时间,只有满足条件后才会切换到下一个状态并改变灯光:
case GREEN:
if (millis() - lightStart >= 3000) {
light = YELLOW;
lightStart = millis();
showLight(yellowPin);
}
break;程序不会停下来等待,因此 loop() 可以处理其他任务。用一个状态灯来验证这一点:让开发板自带的 LED(引脚 13)每隔 500 ms 闪烁一次。
挑战
中等重写计时,不使用 delay():
- 绿灯保持 3000 ms,黄灯保持 1000 ms,红灯保持 3000 ms
- 用
enum表示这三种状态,并使用switch和millis() - 在
setup()中点亮绿灯,并且只在状态改变时调用showLight() - 让 13 号引脚每隔 500 ms 闪烁一次(亮 500 ms,灭 500 ms),持续闪烁
按“运行”,然后按“检查”。
亲手试试
// 汽车车灯
const int redPin = 12;
const int yellowPin = 11;
const int greenPin = 10;
// 打开一盏灯,关闭另外两盏。
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);
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
项目中的所有课
自己练习: Arduino 在线编辑器