【Arduino IDE】プログラムが開始してからの時間を取得する。(micros())

micros() 関数は、Arduino IDE で使用できる関数の一つで、プログラムが開始してからの経過時間をマイクロ秒(µs)単位で取得するために使用されます。Arduinoの内蔵タイマーを利用して、正確なタイミング計測が必要な場合や、高速な処理のタイミングを調整する際に役立ちます。

1. micros() 関数の基本構文

unsigned long micros();

  • 戻り値: プログラム開始からの経過時間(マイクロ秒)を unsigned long 型(32ビットの符号なし整数)で返します。

2. micros() 関数の使い方

micros() 関数は、プログラムが実行を開始してから経過したマイクロ秒を返します。1秒 = 1,000,000 マイクロ秒(µs)なので、非常に短い時間を精密に計測するために使用されます。

例1: 経過時間を表示する

void setup() {
  Serial.begin(9600);
}

void loop() {
  unsigned long time = micros();  // 経過時間をマイクロ秒で取得
  Serial.println(time);           // 経過時間を表示
  delay(1000);                    // 1秒待機
}

このコードでは、プログラム開始からの経過時間をマイクロ秒単位でシリアルモニタに表示します。delay(1000) によって、1秒ごとに経過時間が更新されます。

3. micros() の特性

3.1. オーバーフローについて

  • micros() は、32ビットの符号なし整数でマイクロ秒の値を返します。つまり、最大で約 4,294,967,295 マイクロ秒(約71.6分)までの時間を計測できます。
  • *71.6分後にはオーバーフロー(0に戻る)**ため、長時間のタイミング管理をする際には、オーバーフローの考慮が必要です。ただし、オーバーフローが発生しても、引き算を使って経過時間を正しく計算できます。

例: オーバーフローが起こる場合の処理

unsigned long startTime;

void setup() {
  Serial.begin(9600);
  startTime = micros();  // プログラム開始時のマイクロ秒を記録
}

void loop() {
  unsigned long currentTime = micros();
  unsigned long elapsedTime = currentTime - startTime;  // 経過時間を計算

  Serial.println(elapsedTime);
  delay(1000);  // 1秒待機
}

オーバーフローが発生しても、unsigned long の符号なし整数で計算を行うため、正しい経過時間が計算されます。

3.2. micros() の精度と解像度

  • Arduino Uno や他の多くのボードでは、micros() の精度は4マイクロ秒単位です。つまり、返される値は常に4の倍数となります。
  • より高精度なタイミングが必要な場合は、専用のタイマーを使った手法を検討する必要があります。

3.3. 動作のタイマー依存

  • micros() はハードウェアタイマーに依存しています。これにより、高精度な時間計測が可能ですが、特定のライブラリや他のタイマーを使用する処理(例えば Servo ライブラリ)と同時に使用すると、タイマーが競合し、micros() の動作に影響を与えることがあります。

4. micros()millis() の違い

  • micros() は、マイクロ秒単位で時間を取得します。非常に短い間隔(1秒の1/1,000,000)を測定する必要がある場合に使います。
  • millis() は、ミリ秒単位で時間を取得します。1ミリ秒は1秒の1/1,000なので、やや大まかなタイミングで十分な場合には millis() の方がシンプルです。

例: micros()millis() の違いを確認する

void setup() {
  Serial.begin(9600);
}

void loop() {
  unsigned long microTime = micros();  // マイクロ秒単位で時間を取得
  unsigned long milliTime = millis();  // ミリ秒単位で時間を取得

  Serial.print("micros: ");
  Serial.println(microTime);

  Serial.print("millis: ");
  Serial.println(milliTime);

  delay(1000);  // 1秒待機
}

このコードでは、micros()millis() の両方の経過時間をシリアルモニタに表示し、両者の違いを確認できます。

5. micros() を使ったタイミング制御

Arduinoの標準的な delay() 関数は処理を停止させてしまいますが、micros() を使うことで、ノンブロッキングの時間管理が可能です。これにより、他の処理を同時に進めながらタイミングを制御することができます。

例: ノンブロッキングの時間管理

unsigned long previousTime = 0;  // 最後のイベント時間
const unsigned long interval = 1000000;  // 1秒 (1000000マイクロ秒)

void setup() {
  Serial.begin(9600);
}

void loop() {
  unsigned long currentTime = micros();  // 現在のマイクロ秒を取得

  // 1秒ごとに実行する処理
  if (currentTime - previousTime >= interval) {
    Serial.println("1秒経過");
    previousTime = currentTime;  // 最後のイベント時間を更新
  }

  // 他の処理を続ける(ノンブロッキング)
}

このコードでは、micros() を使ってノンブロッキングで1秒ごとにメッセージを表示します。delay() を使わないため、他の処理が並行して行われます。

6. 実際の用途

  • パフォーマンス計測: 特定のコードブロックの実行時間を測定したり、コードの効率を確認するために使われます。
  • 高速なタイミング制御: センサーデータの取得間隔を精密に制御したり、正確な時間ベースの処理が必要なときに使われます。
  • 通信プロトコルの実装: SPIやI2Cなど、高速なタイミングが重要な通信プロトコルを実装する場合に使用されます。

まとめ

micros() 関数は、Arduinoでマイクロ秒単位の高精度なタイミング計測が必要な場合に使用される重要な関数です。特に、高速な処理や正確な時間制御が必要なプロジェクトでは非常に役立ちます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次