Menu
CoddyTech

用 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 的方式称为状态机。

challenge icon

挑战

中等

机器有 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 状态
  }
}
quiz icon自我测试

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

无需 delay 的计时中的所有课

自己练习: Arduino 在线编辑器