delay() の解説と実装リファレンス

記事内には広告が含まれています。

delay() の解説と実装リファレンス

【概要】

delay()関数は、Arduinoプログラミングにおいて、プログラムの実行を一定時間(ミリ秒単位)停止させるための標準的な関数である。この関数が呼び出されると、メインループの処理が一時停止し、指定された時間が経過するまで次の命令へ遷移しない。これは「ブロッキング(Blocking)」と呼ばれる挙動であり、実行中のタスクを一時的に完全に停止させる性質を持つ。

【仕様】

  • 関数署名: void delay(unsigned long ms);
  • 引数:
    • ms (unsigned long): 待機するミリ秒数。最大値はデータ型の限界(通常4,294,967,295ミリ秒、約49.7日)まで指定可能。
  • 戻り値: void(戻り値なし)
  • 単位: ミリ秒 (ms)
  • 初期状態: システム起動時より、内部タイマー(millis()の基盤)に基づいて動作する。

【技術的特徴】

  • ブロッキング処理: delay()は同期的な処理である。この関数が実行されている間、CPUは他の任意のコード(例えば別のセンサーのポーリングやシリアル通信の処理など)を実行することができない。
  • 割り込み(Interrupts)との関係: 標準的なArduino実装において、delay()はハードウェア割り込みを停止させない。したがって、外部割り込みやタイマー割り込みに基づくバックグラウンド処理は、delay()の実行中であっても継続される。
  • 内部動作原理: delay()の内部では、現在のシステム時間(millis())を取得し、目標とする未来の時刻と比較するループが実行される。指定された時間が経過するまで、このループを繰り返すことで待機を実現する。
  • millis() 関数との比較:
    • delay(): 指定した時間だけプログラムを「止める」ための関数。
    • millis(): 起動時からの経過時間を「取得する」ための関数。非ブロッキングなマルチタスク処理(状態遷移マシンなど)を実装する際は、millis()を用いた比較処理が推奨される。

【注意点】

  • リソースの制約(マルチタスクの欠如): delay()を使用すると、その間はすべてのユーザーコードの実行が停止する。例えば、delay(1000)を呼び出すと、その1秒間はボタン入力の検知や通信パケットの受信処理が行われないため、リアルタイム性が要求されるシステムには不向きである。
  • ウォッチドッグタイマー (WDT): WDTを有効にしている環境において、非常に長いdelay()を呼び出すと、WDTのリセット処理が実行されず、システムがリセットされる可能性がある。
  • 精度の限界: 内部タイマーの分解能に依存するため、マイクロ秒(μs)単位の極めて精密なタイミング制御には、delayMicroseconds()を使用するか、ハードウェアタイマーの直接制御を検討する必要がある。

【サンプルコード】

以下に、delay()を用いた基本的な点滅処理と、設計上の注意点を示す例を記載する。

// 基本的な点滅(ブロッキング処理)
const int LED_PIN = 13;

void setup() {
  pinMode(LED_PIN, OUTPUT);
}

void loop() {
  digitalWrite(LED_PIN, HIGH); // LED点灯
  delay(1000);                 // 1000ミリ秒(1秒)停止

  digitalWrite(LED_PIN, LOW);  // LED消灯
  delay(1000);                 // 1000ミリ秒(1秒)停止

  // 注意:この間、他のセンサーの読み取りなどは一切行われない
}

【活用例】

  • 初期化処理: センサーの電源投入後、安定するまで数ミリ秒〜数百ミリ秒待機する場合。
  • 通信プロトコル: 特定のコマンド送信後、相手機器からの応答を待つための短い待機時間として。
  • プロトタイピング: 複雑な非ブロッキング処理を実装する前に、動作の論理検証を迅速に行うためのデバッグ用途。

コメント

タイトルとURLをコピーしました