用 enum 命名状态
本课属于 Coddy Arduino 学习旅程的“无需 delay 的计时”单元。第 9 课,共 18 课。
编号为 0、1 和 2 的模式可以运行,但 if (mode == 2) 没有说明 2 代表什么。enum 可以为每个数字命名:
enum State { READY, RUNNING, DONE };
State state = READY;第一行创建了一个新类型 State,它只有 READY、RUNNING 和 DONE 这几个值。它们底层仍然是 0、1 和 2,但这些名称说明了每个值的含义。第二行创建了一个该类型的变量。
enum 和 switch 很适合搭配使用:每个状态对应一个 case。
switch (state) {
case READY:
// READY 状态会做什么,以及何时进入下一状态
break;
case RUNNING:
// ...
break;
}要切换到新状态,请设置 state,并记下它开始的时间:state = DONE; stateStart = millis();。随后,每个状态都会通过 millis() - stateStart 来计时。这种编写 sketch 的方式称为状态机。
挑战
中等机器有 3 种状态。READY 已经为你写好:绿色 LED 亮起,按下按钮后机器开始运行。添加另外两种情况:
RUNNING:黄色 LED 亮起。2000 ms 后,将它熄灭并切换到DONE。DONE:红色 LED 亮起。1000 ms 后,将它熄灭并切换回READY。
每次状态改变时都保存 stateStart。按“运行”,再按下按钮,然后按“检查”。
亲手试试
const int buttonPin = 2;
const int greenLed = 10;
const int yellowLed = 11;
const int redLed = 12;
enum State { READY, RUNNING, DONE };
State state = READY;
unsigned long stateStart = 0; // 当前状态开始的时间
void setup() {
pinMode(buttonPin, INPUT_PULLUP);
pinMode(greenLed, OUTPUT);
pinMode(yellowLed, OUTPUT);
pinMode(redLed, OUTPUT);
}
void loop() {
unsigned long now = millis();
switch (state) {
case READY:
digitalWrite(greenLed, HIGH);
if (digitalRead(buttonPin) == LOW) {
digitalWrite(greenLed, LOW);
state = RUNNING;
stateStart = now;
}
break;
// 添加 RUNNING 分支:点亮黄灯;2000 ms 后熄灭黄灯,进入 DONE 状态
// 添加 DONE 分支:点亮红灯;1000 ms 后熄灭红灯,返回 READY 状态
}
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
无需 delay 的计时中的所有课
自己练习: Arduino 在线编辑器