Menu
CoddyTech

enumで状態に名前を付ける

CoddyのArduinoジャーニー「delayを使わないタイミング制御」セクションの一部。レッスン 9/18。

0、1、2と番号を付けたモードでも動作しますが、if (mode == 2)では2が何を意味するのか分かりません。enumを使うと、それぞれの数値に名前を付けられます。

enum State { READY, RUNNING, DONE };
State state = READY;

1行目では、新しい型Stateを作成します。この型が取りうる値はREADY、RUNNING、DONEだけです。内部では引き続き0、1、2ですが、名前を見るとそれぞれが何を意味するか分かります。2行目では、その型の変数を作成します。

enumとswitchは相性がよく、各状態に1つずつcaseを用意します。

switch (state) {
  case READY:
    // READYが行うことと、次の状態に移るタイミング
    break;
  case RUNNING:
    // ...
    break;
}

新しい状態に移るには、stateを設定し、その状態が始まった時刻を記録します。state = DONE; stateStart = millis();。その後、各状態はmillis() - stateStartを使って、それぞれの経過時間を計ります。このようなスケッチの書き方をステートマシンと呼びます。

challenge icon

チャレンジ

中級

マシンには3つの状態があります。READYは用意されています。緑色のLEDが点灯し、ボタンを押すとマシンが起動します。残りの2つのケースを追加してください。

  • RUNNING:黄色のLEDが点灯します。2000 ms後に消灯し、DONEに移行します。
  • DONE:赤色のLEDが点灯します。1000 ms後に消灯し、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;

    // case RUNNING を追加:黄色のLEDを点灯し、2000 ms 後に消灯して DONE に移る

    // case DONE を追加:赤色のLEDを点灯し、1000 ms 後に消灯して READY に戻る
  }
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

delayを使わないタイミング制御のすべてのレッスン

自分で練習してみよう: Arduinoプレイグラウンド