Arduinoでマルチタスクっぽく実行する方法
検証環境
Arduino Leonard
用途
入力待ちをしつつ継続して動作させたい場合等
実装方法
protothreadというライブラリを用いてマルチタスクっぽく実装することができます。
Arduinoのdelayで待ってしまうと全てのスレッドが止まってしまうので、PT_WAIT_UNTILのプリプロセッサマクロを組みましょう。
他のスレッドを待ちたいときはPT_WAIT_THREADです。
サンプルコード
#include <pt.h>
#define PT_WAIT(pt, timestamp, usec) PT_WAIT_UNTIL(pt, millis() - *timestamp > usec);*timestamp = millis();
static struct pt pt1, pt2, pt3;
static int thread1(struct pt *pt) {
// スレッド内で基準となるタイムスタンプ
static unsigned long timestamp = 0;
PT_BEGIN(pt);
while(true) {
// thread1の中身
PT_WAIT(pt, ×tamp, 1000);
Serial.println("thread1");
}
PT_END(pt);
}
static int thread2(struct pt *pt) {
// スレッド内で基準となるタイムスタンプ
static unsigned long timestamp = 0;
PT_BEGIN(pt);
while(true) {
// thread2の中身
PT_WAIT(pt, ×tamp, 1000);
Serial.println("thread2 - 1");
// thread3を待つ
PT_WAIT_THREAD(pt, thread3(&pt3));
PT_WAIT(pt, ×tamp, 1000);
Serial.println("thread2 - 2");
}
PT_END(pt);
}
static int thread3(struct pt *pt) {
// スレッド内で基準となるタイムスタンプ
static unsigned long timestamp = 0;
PT_BEGIN(pt);
while(true) {
// thread3の中身
PT_WAIT(pt, ×tamp, 1000);
Serial.println("thread3 - 1");
PT_WAIT(pt, ×tamp, 100);
Serial.println("thread3 - 2");
break;
}
PT_END(pt);
}
void setup() {
Serial.begin(9600);
// ptを初期化
PT_INIT(&pt1);
PT_INIT(&pt2);
PT_INIT(&pt3);
}
void loop() {
// スレッド開始
thread1(&pt1);
thread2(&pt2);
}
参考文献
-
http://d.hatena.ne.jp/LaclefYoshi/20110129/1296310627
- マルチタスクの章を参考にさせていただいております
-
http://harteware.blogspot.jp/2010/11/protothread-powerfull-library.html
- こちらからArduino用のprotothreadをダウンロードできます
-
http://dunkels.com/adam/pt/examples.html
- いろいろ載ってます