Menu
CoddyTech

millis()を使った信号機

CoddyのArduinoジャーニー「プロジェクト」セクションの一部。レッスン 2/24。

各delay(3000)の間、ボードはほかの処理を何もしないため、次のステップで追加する横断ボタンを検知できません。時間の計測にはmillis()を使います。

信号機は状態機械です。常に1つの状態(青、黄、または赤)にあり、その状態が十分な時間続くと次の状態に移ります。状態にはenumで名前を付け、1つの変数で現在の状態を保持し、別の変数でその状態が始まった時刻を保持します。

enum Light { GREEN, YELLOW, RED };
Light light = GREEN;
unsigned long lightStart = 0;

最初の状態は青なので、setup()で青信号を点灯させます。loop()を実行するたびに、switchが現在の状態が十分な時間続いたかを確認し、続いていた場合にのみ次の状態へ移り、ライトを切り替えます。

case GREEN:
  if (millis() - lightStart >= 3000) {
    light = YELLOW;
    lightStart = millis();
    showLight(yellowPin);
  }
  break;

何も待機しないため、loop()はほかの処理にも使えます。ステータスライトで確かめましょう。ボード本体のLED(ピン13)を500ミリ秒ごとに点滅させます。

challenge icon

チャレンジ

中級

delay()を使わずにタイミングを書き直してください。

  • 緑を3000 ms、黄を1000 ms、赤を3000 ms点灯させる
  • 3つの状態にenumを使い、switchとmillis()を使う
  • setup()で緑を点灯し、状態が変わったときだけshowLight()を呼び出す
  • 常に、13番ピンを500 msごとに点滅させる(500 ms点灯、500 ms消灯)

Runを押してから、Checkを押してください。

自分で試してみよう

// 車用の信号灯
const int redPin = 12;
const int yellowPin = 11;
const int greenPin = 10;

// 1つのライトを点灯し、残りの2つを消灯する。
void showLight(int pin) {
  digitalWrite(redPin, LOW);
  digitalWrite(yellowPin, LOW);
  digitalWrite(greenPin, LOW);
  digitalWrite(pin, HIGH);
}

void setup() {
  pinMode(redPin, OUTPUT);
  pinMode(yellowPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
}

void loop() {
  showLight(greenPin);
  delay(3000);
  showLight(yellowPin);
  delay(1000);
  showLight(redPin);
  delay(3000);
}
quiz icon腕試し

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

プロジェクトのすべてのレッスン

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