Menu
CoddyTech

遅延なしで点滅

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

delay()はスケッチ全体を停止します。点滅のために500 ms待っている間、loop()内のほかの処理は何も実行されません。その間にボタンが押されても、待ち時間が終わるまで検知されません。

解決策は、決して待たないことです。loop()を何度も非常に速く実行し、そのたびに現在時刻とLEDが最後に切り替わった時刻を比較します。500 msが経過するまでは何もしません。その後、LEDを切り替えて新しい時刻を保存します:

const unsigned long interval = 500;
unsigned long previousMillis = 0;   // LEDが最後に切り替わったとき

void loop() {
  unsigned long now = millis();
  if (now - previousMillis >= interval) {
    previousMillis = now;           // この時点を記録する
    // ここでLEDを切り替える
  }
  // ここに書いたほかの処理は1秒間に数千回実行される
}

now - previousMillisは、最後に切り替わってからの経過時間です。LEDを切り替えるには、状態をint redState = LOW;のように変数に保持し、if/elseで反転させて、digitalWrite(redLed, redState);で書き込みます。

previousMillisの更新を忘れると、最初の500 msが経過した後も条件がtrueのままになり、LEDはループのたびに切り替わって、半分点灯しているように見えます。

challenge icon

チャレンジ

中級

黄色の LED はボタンに連動するはずですが、赤色 LED の delay() 呼び出しによってループが停止するため、反応が遅れます。millis() を使って赤色 LED の点滅を書き換えましょう。

  • ボタンの部分はそのままにする
  • 500 ms ごとに、13 番ピンの赤色 LED のオン/オフを切り替える
  • delay() はどこにも使わない

Run を押し、ボタンを押したまま両方の LED を確認してから、Check を押してください。

自分で試してみよう

const int redLed = 13;
const int yellowLed = 12;
const int buttonPin = 2;

void setup() {
  pinMode(redLed, OUTPUT);
  pinMode(yellowLed, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);
}

void loop() {
  // 黄色のLEDはボタンの状態に連動します。この部分は残してください。
  if (digitalRead(buttonPin) == LOW) {
    digitalWrite(yellowLed, HIGH);
  } else {
    digitalWrite(yellowLed, LOW);
  }

  // 赤色のLEDは点滅しますが、各delay()によって上の行の処理が
  // 0.5秒間止まります。この部分をmillis()を使って書き直してください。
  digitalWrite(redLed, HIGH);
  delay(500);
  digitalWrite(redLed, LOW);
  delay(500);
}
quiz icon腕試し

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

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

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