LoginSignup
16
17

More than 5 years have passed since last update.

Arduinoでマルチタスクっぽく実行する方法

Last updated at Posted at 2017-01-26

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, &timestamp, 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, &timestamp, 1000);
        Serial.println("thread2 - 1");

        // thread3を待つ
        PT_WAIT_THREAD(pt, thread3(&pt3));

        PT_WAIT(pt, &timestamp, 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, &timestamp, 1000);
        Serial.println("thread3 - 1");

        PT_WAIT(pt, &timestamp, 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);
}

参考文献

16
17
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
17