第9回 解答例
RobotStateで状態管理する
演習の解答例。まず自分で書いてから読むこと。
解答
#include <Arduino.h>
enum class RobotState {
STOP,
MOVE,
ERROR
};
const int LED_PIN = LED_BUILTIN;
const int ERROR_BLINK_MS = 100;
RobotState state = RobotState::STOP;
void setState(RobotState next) {
state = next;
}
void updateLed() {
switch (state) {
case RobotState::STOP:
digitalWrite(LED_PIN, LOW);
break;
case RobotState::MOVE:
digitalWrite(LED_PIN, HIGH);
break;
case RobotState::ERROR:
// 点滅させる
digitalWrite(LED_PIN, HIGH);
delay(ERROR_BLINK_MS);
digitalWrite(LED_PIN, LOW);
delay(ERROR_BLINK_MS);
break;
}
}
void setup() {
pinMode(LED_PIN, OUTPUT);
setState(RobotState::MOVE);
}
void loop() {
updateLed();
delay(50);
}なぜenum classなのか
数値で状態を持つと、次のようなコードが書けてしまう。
int state = 0; // 0=STOP, 1=MOVE, 2=ERROR ... コメントがないと読めない
state = 7; // 存在しない状態。コンパイラは何も言わないenum classなら、
RobotState state = RobotState::STOP;
state = 7; // コンパイルエラー
state = RobotState::MOVE; // これしか書けない- 存在しない状態を代入できない
switchの各caseが何を表すか名前で読めるMANUALのような名前が他のenumと衝突しない(enumとの違い)
状態を切り替える
void loop() {
if (Serial.available() > 0) {
char command = Serial.read();
switch (command) {
case 's':
setState(RobotState::STOP);
break;
case 'm':
setState(RobotState::MOVE);
break;
case 'e':
setState(RobotState::ERROR);
break;
default:
break;
}
}
updateLed();
}