Menu
CoddyTech

Именованные состояния с enum

Часть раздела Отсчёт времени без delay путешествия по Arduino на Coddy. Урок 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. Такой способ написания скетча называется конечным автоматом.

challenge icon

Задание

Средне

У машины три состояния. Для вас уже написано READY: зелёный светодиод горит, а нажатие запускает машину. Добавьте два других случая:

  • RUNNING: горит жёлтый светодиод. Через 2000 мс выключите его и перейдите в DONE.
  • DONE: горит красный светодиод. Через 1000 мс выключите его и вернитесь в READY.

Сохраняйте stateStart при каждом изменении. Нажмите Run, нажмите кнопку, затем нажмите Check.

Попробуйте сами

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 мс выключите его и перейдите в DONE

    // добавьте ветку DONE: включите красный светодиод; через 1000 мс выключите его и вернитесь в READY
  }
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Отсчёт времени без delay

Потренируйтесь самостоятельно: Песочница Arduino