无延迟闪烁
本课属于 Coddy Arduino 学习旅程的“无需 delay 的计时”单元。第 3 课,共 18 课。
delay()会停止整个程序。在闪烁等待 500 ms 期间,loop()中的其他内容都不会运行:这段时间按下的按钮要等到等待结束后才会被检测到。
解决方法是永远不等待。让loop()快速地一遍又一遍运行,每次都将时钟与 LED 上次变化的时刻进行比较。在经过 500 ms 之前,什么也不做。然后改变 LED,并存储新的时刻:
const unsigned long interval = 500;
unsigned long previousMillis = 0; // LED 上次改变状态的时间
void loop() {
unsigned long now = millis();
if (now - previousMillis >= interval) {
previousMillis = now; // 记住这一刻
// 在这里切换 LED 的状态
}
// 这里的其他代码每秒会运行数千次
}now - previousMillis表示距离上次变化所经过的时间。要切换 LED,请用变量保存它的状态:int redState = LOW;,用if/else切换状态,并用digitalWrite(redLed, redState);写入状态。
如果忘记更新previousMillis,那么经过最初的 500 ms 后,条件就会一直为真,因此 LED 会在每次循环时都变化,看起来像是亮度减半。
挑战
中等黄色 LED 应该跟随按钮变化,但它反应较慢,因为红色 LED 的 delay() 调用会阻塞循环。用 millis() 重写红色 LED 的闪烁逻辑:
- 保持按钮部分不变
- 每隔 500 ms,切换引脚 13 上红色 LED 的状态
- 任何地方都不能使用
delay()
按“运行”,按住按钮并观察两个 LED,然后按“检查”。
亲手试试
const int redLed = 13;
const int yellowLed = 12;
const int buttonPin = 2;
void setup() {
pinMode(redLed, OUTPUT);
pinMode(yellowLed, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
}
void loop() {
// 黄色 LED 随按钮状态变化。保留这部分。
if (digitalRead(buttonPin) == LOW) {
digitalWrite(yellowLed, HIGH);
} else {
digitalWrite(yellowLed, LOW);
}
// 红色 LED 会闪烁,但每次调用 delay() 都会让上面的代码暂停
// 半秒。用 millis() 重写这部分。
digitalWrite(redLed, HIGH);
delay(500);
digitalWrite(redLed, LOW);
delay(500);
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
无需 delay 的计时中的所有课
自己练习: Arduino 在线编辑器