2022/08/01

M5Stack(ESP32)でサーボモータを使う


 M5Stackイラスト ← M5Stackはこんなやつ。

M5Stackでサーボモータを制御する方法をまとめました。
ESP32マイコンでサーボモータを使う場合も同様の手順で制御できます。

サーボモータにはPWMサーボと、シリアルサーボがあります。

本記事ではPWMサーボの制御について説明しています。

サーボモータの制御方法

以降で3通りの方法を紹介します。

  1. ESP32マイコンのLED Control機能でPWM信号を生成する
  2. ESP32Servoライブラリを使用する
  3. ServoEasingライブラリを使用する

M5Stackからサーボモータへ出力するPWM信号は下記のようになります。
制御パルスの幅で回転角を指定します。
(周波数50Hz、パルス幅0.5ms~2.5ms辺りで制御することが多いようです。)


サーボモータへ入力するPWM信号

使うサーボモータによって制御パルス幅の仕様が違いますので、データシートなどで制御パルス幅をご確認ください。

※ 本記事では動作確認に「SG92R」というサーボモータを使用していて、制御パルス幅は0.5ms~2.4msになります
※ M5Stackからサーボモータへ電源を供給する場合、負荷によっては供給しきれずにM5Stackが再起動してしまう場合があります。
 その場合は、外部から電源を持ってくる必要があります。

  サーボモータとM5Stackの接続

LED Control機能でPWM信号を生成する

M5StackにはESP32というマイコンが搭載されています。
このESP32に標準装備されている「LED Control」機能でPWMを生成できます。

  ESP-IDF ProgramingGuide LED Control (LEDC)

arduinoでこの機能を使うには、LEDC関数を使用します。

  arduino-esp32 esp32-hal-ledc.h
  arduino-esp32 esp32-hal-ledc.c

ソースコードは以下になります。

// ledcSetup(uint8_t channel, uint32_t freq, uint8_t resolution_bits)
ledcSetup(0, 50, 8);

// ledcAttachPin(uint8_t pin, uint8_t channel)
ledcAttachPin(2, 0);

// ledcWrite(uint8_t channel, uint32_t duty)
ledcWrite(0, 13);   // 制御パルス1ms

ledcSetup

ledcAttachPin

ledcWrite


PWM信号とレゾリューションの関係

ESP32Servoライブラリを使う

上記のLEDC関数は、制御パルス幅を周波数とレゾリュ―ションbitから計算する必要があり、ひと手間かかります。
これを簡単にしてくれるのがESP32Servoライブラリです。
setPeriodHertz ⇒ attach ⇒ write で、角度を指定して制御ができます。
だいぶらくちんですね。

ちなみに、ライブラリの中身を見てみるとLEDC関数を使ってPWM制御しています。

  arduino ESP32Servoライブラリ

#include <ESP32Servo.h>
Servo servo1;

// setPeriodHertz(int hertz)
servo1.setPeriodHertz(50);

// attach(int pin, int min, int max)
servo1.attach(2, 500, 2400);

// write(int value)
servo1.write(90);

setPeriodHertz

attach

write

ServoEasingライブラリを使う

方法1と2では、サーボの回転角の指定はできますが、動かし方(回転速度の設定、最初と最後はゆっくり、など)の制御まではできませんでした。
ServoEasingライブラリを使用すると、細かな動作の制御までできるようになります。

  arduino ServoEasingライブラリ

注意:ServoEasingは内部でESP32Servoライブラリを使用しているので、ダウンロードしておく必要があります。

#include <ServoEasing.hpp>
ServoEasing servo1;

// attach(int aPin, int aInitialDegreeOrMicrosecond, int aMicrosecondsForServo0Degree, int aMicrosecondsForServo180Degree)
servo1.attach(G5, 90, 500, 2400);

// setEasingType(uint_fast8_t aEasingType)
servo1.setEasingType(EASE_QUADRATIC_IN_OUT);

// setEaseToD(int aTargetDegreeOrMicrosecond, uint_fast16_t aMillisForMove)
servo1.setEaseToD(90, 500);

// synchronizeAllServosStartAndWaitForAllServosToStop()
synchronizeAllServosStartAndWaitForAllServosToStop();

attach

setEasingType

setEaseToD

synchronizeAllServosStartAndWaitForAllServosToStop


他にも機能がたくさんあるのですが、ドキュメントがないのでソースを見て、良さそうな関数があれば使ってみてください。

サーボモータの紹介

この記事では、SG92Rというサーボモータを使用しています。
値段がお手頃で使いやすいです。

秋葉原へ行けるのであれば、秋月電子でも購入できます。

また、他のサーボについては、以下のサイトが長所・短所がまとまっておりお勧めです。
スタックチャン M5GoBottom版で試したPWMサーボ(SG90系)


以上です。


コメント(githubのアカウントが必要です)