Arduinoでタイマ/スレッドプログラミング

Arduinoで、定期的に何か動作をさせたい場合がある。そういう場合は、タイマやスレッドを用いることが出来る。勿論、Arduino環境らしく、ライブラリで簡単に使えるようになっている。

タイマ

Arduinoでタイマを使うなら、定番はhttp://arduino.cc/playground/Main/MsTimer2らしいが、最近はArduino Playground - FlexiTimer2も使われるようになっているようだ。両ライブラリはメソッド互換があるので、FlexiTimer2を使うことにする。
FlexiTimer2を使って、2個のLEDを点滅させるプログラムを書いた。1つは1000ミリ秒、もう1つは2000ミリ秒間隔で点滅する、はずだった。しかし、結果は片方は2000ミリ秒間隔で点滅を繰り返したが、もう片方は点灯すらせず沈黙したままだった。

つまり、FlexiTimer2では(MsTimer2でも)2つ以上のタイマを設置できない。

2つ以上のタイマ動作が必要なら、http://www.arduino.cc/playground/Code/Metroを使うのが良い。

loop()の中でMetro.check()が必要なのがダサいが、上手く動作する。

スレッド

もちろん、ATmega (Arduinoが搭載しているマイクロコントローラチップ)はマルチスレッドに対応していない。しかし、このような環境でもスレッドプログラミングを実現するライブラリがある。それが、protothreadsである。

Protothreads are extremely lightweight stackless threads designed for severely memory constrained systems, such as small embedded systems or wireless sensor network nodes.

protothreadsはArduino用ライブラリとして設計されていないが、Arduinoで使うためのチュートリアルArduino Playground - GeneralCodeLibraryhttp://arduinocollective.com/2009/12/05/arduino-threading/にある。

protothreadsを使って、2個のLEDがそれぞれ1000ミリ秒、2000ミリ秒間隔で点滅するプログラムを書いた。

protothreadsはタイマ動作のためのライブラリではない。PT_WAIT_UNTIL(pt, CONDITION)の条件を設定することで、あたかもマルチスレッドを使ってプログラミング/動作しているかのように見せることが出来る。



まとめとして、protothreadsとMetroを使って、4個のLEDを点滅させてみた。LED1とLED2をprotothreads、LED3とLED4をMetroで制御する。LED1とLED3は1000ミリ秒、LED2とLED4は2000ミリ秒間隔で点滅する。

動いている様子も撮影した。左から、LED1(protothreads:1000ミリ秒)、LED2(protothreads:2000ミリ秒)、LED3(Metro:1000ミリ秒)、LED4(Metro:2000ミリ秒)である。

LED1とLED2の点滅テンポが段々ずれていき、3分も過ぎれば正確なタイマ動作になっていないことが分かる。つまり、protothreadsはタイマのように、等時間間隔で何かをさせる、といった動作の実装には向かないことが分かった。

protothreadsの使い道はArduinoの様な環境だとなかなか難しいが(protothreadsを使わなくても、したい事が出来てしまう場合が多いので)、ユーザや環境と頻繁に交流をするような設計では役に立つかもしれない。