ESP32のマルチスレッドで複数のサーボモータを同時に動かす方法

ESP32のマルチスレッドで複数のサーボモータを同時に動かす方法
ESP32のマルチスレッドで複数のサーボモータを同時に動かす方法

ESP32で複数のサーボモーターを同時に動かす方法をご紹介します。

ゴール

RTOSのタスクを使って、動画のように2つのサーボーモータを独立して動かします。

なんの工夫もなしに delay 関数を使ってサーボモータを動かそうとすると、ひとつのサーボモータの処理が終わるまで待たなければならず、同時に動かすことが難しいです。非ブロッキングなポーリング処理(コルーチン)で動かすやり方も考えられますが、コーディングが複雑になり管理が難しいです。ESP32ならばFree RTOSのタスク機能(マルチスレッド)が使えますので、簡単に複数のサーボモータを動かすことが可能です。

ESP32のマルチスレッドで複数サーボを同時に動かす

ソースコード

次のコードは、FreeRTOSのタスク利用してマルチスレッドで複数サーボモータを制御する例です:

cpp
#include <Arduino.h>
#include <ESP32Servo.h>

#define SERVO_A_PIN 32
#define SERVO_B_PIN 33

Servo servoA, servoB;

const int pulse_min = 544; // default 544us
const int pulse_max = 2400; // default 2400us

// プロトタイプ宣言
void taskServoA(void * parameter);
void taskServoB(void * parameter);

void setup() {
    Serial.begin(115200);
    servoA.attach(SERVO_A_PIN, pulse_min, pulse_max);
    servoB.attach(SERVO_B_PIN, pulse_min, pulse_max);
    servoA.write(5); // リセット
    servoB.write(5); // リセット
    delay(2000);

    // FreeRTOSを使用してタスクを作成
    xTaskCreate(taskServoA, "TaskServoA", 10000, NULL, 1, NULL);
    xTaskCreate(taskServoB, "TaskServoB", 10000, NULL, 1, NULL);
}

void loop() {
}

void taskServoA(void * parameter) {
    for (;;) {
        for (int pos = 5; pos <= 180; pos += 1) {
            servoA.write(pos);
            vTaskDelay(2 / portTICK_PERIOD_MS);
        }
        vTaskDelay(700 / portTICK_PERIOD_MS);

        for (int pos = 180; pos >= 5; pos -= 1) {
            servoA.write(pos);
            vTaskDelay(2 / portTICK_PERIOD_MS);
        }

        vTaskDelay(700 / portTICK_PERIOD_MS);
    }
}

void taskServoB(void * parameter) {
    for (;;) {
        for (int pos = 5; pos <= 180; pos += 1) {
            servoB.write(pos);
            vTaskDelay(6 / portTICK_PERIOD_MS);
        }
        vTaskDelay(300 / portTICK_PERIOD_MS);

        for (int pos = 180; pos >= 5; pos -= 1) {
            servoB.write(pos);
            vTaskDelay(6 / portTICK_PERIOD_MS);
        }

        vTaskDelay(300 / portTICK_PERIOD_MS);
    }
}

解説

サーボモータを、0度から180度へ行き来させるプログラミングです。サーボモータの制御は、ESP32Servo ライブラリを使用しました。

本来は pos = 0 とすべきですが、サーボモータが震えてしまうため、5度までを下限として pos = 5 のように宣言してます。

xTaskCreate で、タスク(スレッド)を作成します。

一時停止を行いたい場合は delay 関数を使わずに、 vTaskDelay で処理します。vTaskDelay は、タスクを指定した時間だけブロック(一時停止)できます。

関連記事

最後までご覧いただきありがとうございます!

▼ 記事に関するご質問やお仕事のご相談は以下よりお願いいたします。
お問い合わせフォーム