Arduinoでなんらかの時間的に正確な処理をしたい時、Arduinoのタイマーライブラリを利用すると簡単に出来る。ArduinoのタイマーライブラリはMsTimer2とTimerOneがあり、これらのライブラリを利用すると、一定時間ごとに関数を「割り込み(interrupt)」で呼び出す、ということがさくっと出来る。
Arduinoのタイマー
Arduinoはハードウェアの機能としてタイマーを持っていて、これはArduinoで使用しているAVRというマイコンの機能で、各種ライブラリ上から使われている。Arduinoで使用している主要なAVRマイコン*1では、Timer0、Timer1、Timer2の3つのタイマーがある。これらのハードウェアのタイマーを利用し、一定時間ごとにある関数を「割り込み(interrupt)」で呼び出すことをArduinoのタイマー系ライブラリは実現している。
- Timer0 8bitのタイマーでArduinoの時間を管理する用途で利用されている。delay(), millis(), micros()などである。UNOでは5,6番ピンのPWMで利用されている。
- Timer1 16bitのタイマーでUNOではServoライブラリと9,10番ピンのPWMで利用されている。
- Timer2 8bitのタイマーでUNOではtone()と3,11番ピンのPWMで利用されている。
上記のTimerの説明にある通り、AVRのタイマー機能はArduinoの各種ライブラリによって利用されていて、タイマーライブラリを使う際は、利用されていないタイマーを使うなど競合を避けないければならない。PWMもまた、タイマーを利用しているため、同時に使用することは出来ない。
タイマーライブラリ
今回紹介するライブラリは、Arduinoソフトウェア(v1.6.3)の下記階層に行くと、Library Managerが起動し、そこからインストールすることが出来る。
スケッチ > Include Library > Manage Libraries...
MsTimer2
Arduino Playground - MsTimer2
最も利用されるTimer2を利用したシンプルなライブラリ。まずはこれの利用を検討するとよい。
100ms毎に呼びだすサンプル。
#include <MsTimer2.h> void timerFire() { //100ms毎にここが呼び出される } void setup() { //100ms毎にtimer発火 MsTimer2::set(100, timerFire); MsTimer2::start(); } void loop() { }
TimerOne, TimerThree
TimerOne & TimerThree Arduino Libraries
Timer2以外のTimerを利用したライブラリ。Timer2が使えなかったり、複数個のタイマーを使いたいときに。また、MsTimer2に比べてより細かく設定が可能。TimerOneとTimerThreeの利用の仕方はまったく同じだが、TimerThreeはTimer3以上が実装されたArduino MEGA等でないと当然使えない。
同じく100ms毎に呼び出すサンプル。
#include <TimerOne.h> void timerFire() { //100ms毎にここが呼び出される } void setup() { Timer1.initialize(100); //マイクロ秒単位で設定 Timer1.attachInterrupt(timerFire); } void loop() { }
割り込み(interrupt)
割り込みもまたマイコンの機能のひとつで、割り込みはある事柄が発生した時に、処理を割りこませるという機能である。今回はTimerがある一定時間経つと割り込みを発生させるということになる。割り込みの発生源としては、他に外部入力などがある。割り込みが発生するとソフトウェア上では、あらかじめ指定された関数のところに処理が飛ばされる。今回のサンプルプログラムではtimerFireという関数を呼び出している。
利用時のソフトウェア面での注意
割り込みしたときと、メインループ(Arduinoではloop()の中とそこから呼び出している関数)の時とで、共有して使いたい変数がある場合、volatile属性をつけないと値が共有されないので注意する必要がある。
volatile int value;