プログラミング素人のはてなブログ

プログラミングも電気回路も専門外の技術屋の末端が勉強したことや作品をアウトプットするブログ。コードに間違いなど見つけられたら、気軽にコメントください。 C#、Python3、ラズパイなど。

Arduinoで時間を計る

f:id:s51517765:20181129232335j:plain

Arduinoで時間を扱うにはどうすればいいかといえば、delay()という関数があります。
しかし、これは指定時間のあいだ処理をstopするという意味にはなりますが、時間を計測しようとするときには正確ではありません。
ここで、 millis()micros() を使います。

まず、delay()とこれらの違いを簡単に見てみます。

nt time_u =0; 
int time_m =0;

void setup() {

Serial.begin(57600);
}

void loop() {

time_u = micros();
time_m= millis();

Serial.print("us =");
Serial.print(time_u);
Serial.print(" ");
Serial.print("ms =");
Serial.println(time_m);

delay(300);
}

us =48 ms =0
us =300348 ms =300
us =600948 ms =600
us =901552 ms =901
us =1202148 ms =1201
us =1502844 ms =1502
us =1803544 ms =1803
us =2104236 ms =2103
us =2404932 ms =2404
us =2705632 ms =2705

このような形で、次々時間が吐き出されていきます。
当然のことながらusとmsは1000倍異なります。
ここで、300msでdelayを設定しているのに、900msのところが早速901となっています。
usでも同じようにずれています。これは、プログラムの実行によって loop() の実行に遅れが生じていると確認できます。
この結果をグラフにすると、32,000ぐらいで、ひっくり返っていることが分かります。

f:id:s51517765:20160919131300p:plain

これは、int の最大値が 2^15-1 だからだそうです。
時間を計るには millis()で32秒、 micros()では0.032秒しか測定できないことになり、不十分なので、unsigned longを使います。

int で定義していた time_m 、time_uをunsigned longで定義します。unsigned longであれば、最大値は2^32なのでmillis()であれば、1193時間まで測定できます。