M5Stack等のESP32系マイコンボードを使ったサーボモーター(RCサーボ)の制御方法を紹介します。
サーボモーターの制御には「PWM制御」の理解が必要ですが、今回はサーボ用ライブラリ「ESP32Servo」を使用して、角度指定で簡単に制御する方法を紹介します。
ライブラリを使えば、使用するサーボの特性を入力して、角度を指定して実行するだけで簡単に制御することができるので、ぜひチャレンジしてみましょう。
ライブラリを使用しないサーボの制御方法は以下で詳しく紹介しています。
1.サーボモーター(RCサーボ)とは
「サーボモーター」とは、電圧を加えたら回転し続けるモーターとは違い、角度や、回転速度を指定することで、指定した通りに動作しその状態を保持しようとするモーターです。
モーター内部にはモーターの回転部の位置を検知するためのセンサが内蔵されており、このセンサの情報を元に角度や回転数を制御しています。
今回紹介するのはモーター出力軸の回転角度を制御することができるモーターで、主にラジコン(Radio Control)カーのステアリング部やラジコン飛行機の羽の角度調整に使われているため「RCサーボ」と呼ばれているものです。
「RCサーボ」には内部にモーターや制御回路、位置検出センサ、ギヤが内蔵され、コンパクトなケースに収まっています。
2.RCサーボの動作原理
一般的な回転モーターが電圧を加えると回転し続けるのに対して「RCサーボ」は電圧を加えただけでは動作しません、動作させるには動作角度を指定する制御信号も与える必要があります。
「RCサーボ」の動作原理を安価で入手しやすい「SG90」を例に紹介します。
以下が「SG90」の外観写真です。
動作角度は0°〜180°で、コネクタの配線は3本あり一般的には「赤:電源[+]、茶:GND[0V]、黄:制御信号」の場合が多いですが、サーボによっては異なる場合もあるため使用する前にデータシート等でよく確認しましょう。
制御信号にはパルス状の電圧信号を与えます。このようなパルス状の電圧波形で制御する方法を「パルス幅変調(Pulse Width Modulation)制御」略して「PWM制御」と言います。
「RCサーボ」の動作角度は、このパルス状の電圧波形の中で「電圧が高い状態のパルス幅の時間」を指定することで角度が制御でき「SG90」では以下のような仕様になっています。
制御信号 パルス幅時間 | RCサーボ 制御角度 |
---|---|
500μs 〜 2400μs (0.5ms 〜 2.5ms) | 0゜〜 180゜ |
実際の動作は下図のようになります。
パルス幅時間が500μs(0.5ms)の時に動作角度0°、2400μs(2.4ms)の時に180°、中間の動作角度はパルス幅時間の比率で指定され、真ん中のパルス時間幅の1450μs(1.45ms)にすると動作角度は90°になります。
「PWM制御」の使い方については以下のリンクで詳しく紹介しています。
3.動作紹介
「M5Stack」社製の「ATOM LITE」を使用して「RCサーボ」を制御するサンプルプログラムを準備しました。
このプログラムで動作確認を行ったものが下写真のようになります。
外付けのボリュームを使用して、ボリュームを回転させることで「RCサーボ」の回転軸の動作角度を操作できます。
左写真の動作角度 0°(パルス幅500μs)から、右写真の 180°(パルス幅2400μs)の範囲内でボリュームによって、サーボの角度を制御しています。
「ATOM LITE」本体にはボタンがあり(写真の「ATOM LITE」本体の裏側)このボタンを押すと、プログラム内で指定した任意の角度に動作させることができます。
4.準備するもの
準備するものは以下になります。
「ジャンパー線」と「ピンヘッダー」はどちらかあれば大丈夫です。
「ジャンパー線」はごちゃごちゃするので個人的には好きではありませんが、自由度は高いので動作確認用としては確実に接続できて便利です。
「ピンヘッダーL型」はコンパクトに端子が引き出せて配線がすっきりするのでよく使います。
ただ、このままでは「ATOM LITE」側の挿さりが浅いため、動作確認用として考えて使用してください。
「ATOM LITE」と「ボリューム」については以下のリンクで詳しく紹介しています。
「ATOM LITE」の使用が初めてで、開発環境から準備したい方は以下のリンクで始め方を詳しく紹介しています。
5.サンプルプログラム(コピペ)
プログラムは以下に準備しましたので「コピペ」して書き込んでください。
※コピーは下コード(黒枠)内の右上角にある小さなアイコンのクリックでもできます。
#include <M5Atom.h>
#include <ESP32Servo.h>
//FastLED(CRGB構造体)設定
CRGB dispColor(uint8_t r, uint8_t g, uint8_t b) {
return (CRGB)((r << 16) | (g << 8) | b);
}
Servo servo1; // 使用するサーボ毎にインスタンスを準備
// 変数設定
float ad_val; // アナログ入力値
int angle; // 動作指示値格納用(角度またはDutyパルス幅時間(μs)※自動判別)
// 初期設定 -----------------------------------------
void setup() {
M5.begin(false, false, true); // 本体初期化(UART, I2C, LED)
Serial .begin (9600); // シリアル出力初期設定
pinMode(32, ANALOG); // アナログ入力端子設定
M5.dis.drawpix(0, dispColor(0, 50, 50)); // LED点灯
// PWM設定(以下のタイマ1つで4チャンネル使用可のため、最大16台の設定が可能)
ESP32PWM::allocateTimer(0); // ledcチャンネル 0,1,8,9用タイマ(C Plusではノイズ音が鳴るため非推奨)
// ESP32PWM::allocateTimer(1); // ledcチャンネル 2,3,10,11用タイマ割当許可
// ESP32PWM::allocateTimer(2); // ledcチャンネル 4,5,12,13用タイマ割当許可
// ESP32PWM::allocateTimer(3); // ledcチャンネル 6,7,14,15用タイマ割当許可
// サーボ設定(使用するサーボ毎に設定)
servo1.setPeriodHertz(50); // 周波数設定(一般的なRCサーボは50Hz)
servo1.attach(25, 500, 2400); // サーボ設定(端子番号, 最小角度Dutyパルス幅μs, 最大角度Dutyパルス幅μs)
}
// メイン -------------------------------------------
void loop() {
M5.update(); //本体ボタン状態更新
if (M5.Btn.isPressed()) { // ボタンが押されていたら指定角度で動作
angle = 30; // 角度指定
servo1.write(angle); // 角度を指定してサーボ動作実行(「最小角度Dutyパルス幅時間μs」以下の場合は角度として扱われ、それ以外はパルス幅μsとして扱われます。)
} else { // ボタンが押されてなければボリュームで角度調整
ad_val = analogRead(32); // アナログ入力値(0〜4095)を取得
angle = map(ad_val, 0, 4095, 0, 180); // アナログ値 (0〜4095)→ 角度(0゜〜180゜)換算
servo1.write(angle); // 角度を指定してサーボ動作実行(「最小角度Dutyパルス幅時間μs」以下の場合は角度として扱われ、それ以外はパルス幅μsとして扱われます。)
}
// シリアルモニタ出力(角度、Dutyパルス幅時間μs)※使用する場合は有効にしてdelay時間長くする。
// Serial.printf("Angle : %d' Pulse Width(us) : %d\n", servo1.read(), servo1.readMicroseconds());
delay(100); // 遅延時間
}
6.ライブラリ「ESP32Servo」の使い方
「RCサーボ」制御ライブラリ「ESP32Servo」の使い方を紹介します。
ライブラリを使用するには開発環境にライブラリ「ESP32Servo」をインストールしておく必要がありますので、開発環境に合わせて以下のリンクを参考にインストールしてください。
「ArduinoIDE」の場合
「PlatformIO」の場合
まず、サンプルプログラムの 2行目のように「ESP32Servo」のヘッダーファイルを準備します。
次に、 7行目でクラス「Servo」のインスタンスを準備します。
ここでは以下のように、使用するサーボに好きな名前をつけて、このサーボ名で「Servo」というクラスを使用していろいろできるようにしています。
Servo サーボ名2 ; // 複数使用する場合は同様に複数記入
・Servo:サーボを制御するためのクラス(プログラムの集合体のようなもの)
・サーボ名:使用するサーボ毎にわかりやすい名前を任意に指定(サンプルプログラムではServo1)
以降サーボの設定をする時はこの「サーボ名」を使用する
18行目 〜 22行目でPWM出力に使用するチャンネルやパルスを発生するために使用するタイマーの割り付けを行なっています。今は特に気にせずにそのまま記入してください。
割り付けられるタイマーは4つあって、タイマー1つで4個のサーボの制御が可能なため合計で16個のサーボの設定ができるようになっていますが台数分の出力端子も必要なため、使用するサーボの台数に合わせて、コメントを外して有効にして設定しましょう。
24行目 〜 26行目でサーボに使用する出力端子と、最小角度パルス幅時間μs、最大角度パルス幅時間μsを使用するサーボ毎に設定します。
サーボ名1. attach ( 端子番号, 最小角度パルス幅時間, 最大角度パルス幅時間 ) ; // サーボ設定1
サーボ名2. setPeriodHertz ( 周波数 ) ; // 周波数設定2(一般的なRCサーボは50Hz)
サーボ名2. attach ( 端子番号, 最小角度パルス幅時間, 最大角度パルス幅時間 ) ; // サーボ設定2
・サーボ名: 7行目で準備したインスタンス(サーボ名)を指定、複数あれば台数分指定
・setPeriodHertz:制御信号パルスの周波数を設定
・周波数:周波数(Hz)の値を指定しますが一般的なRCサーボは50Hzです
・attach:サーボ毎に出力端子番号と、最小と最大角度パルス幅時間を設定
・端子番号:制御信号のパルスを出力する端子番号を指定
・最小角度パルス幅時間:最小角度時の制御信号パルス幅時間(μs)を指定
・最大角度パルス幅時間:最大角度時の制御信号パルス幅時間(μs)を指定
34行目 と 38行目でサーボの動作角度を指定することで、指定した角度に動作させています。
ここでは「角度」で指定していますが「パルス幅時間μs」でも指定可能です。
サーボ名2. write ( 角度の値、またはパルス幅時間μs) ; // サーボ2動作実行
・サーボ名: 7行目で準備したインスタンス(サーボ名)を指定、複数台でも個別に設定可
・write:指定した角度またはパルス幅時間でサーボ動作を実行
・角度の値、またはパルス幅時間μs:角度の値(サンプルプログラムでは 0〜180)を指定
「最小角度パルス幅時間μs」以下の場合は角度として扱われ、それ以外はパルス幅μsとして扱われます。
34行目のサーボ動作実行では角度を指定しておいて、本体ボタンが押されたときにその角度に動作するようにしています。
38行目のサーボ動作実行では本体ボタンが押されていない間ずっと実行され続け、ボリュームからのアナログ入力値を、指定したい動作範囲に換算して、動作角度を指定して実行しています。
アナログ入力値を、指定したい動作範囲に換算するには「Aruduino」コマンドの「map関数」が便利なのでここで紹介しておきます。
・変換対象:変換対象の変数等を指定(サンプルプログラムでは「ad_val」)
・変換対象の最小値:変換対象の最小値を指定(サンプルプログラムでは0)
・変換対象の最大値:変換対象の最大値を指定(サンプルプログラムでは4095)
・変換後の最小値:変換後の最小値を指定(サンプルプログラムでは0)
・変換後の最大値:変換後の最大値を指定(サンプルプログラムでは180)
サンプルプログラムではボリュームからの入力電圧(0〜3.3V)から取得した12bit(分解能4096)のアナログ入力値 「0〜4095」を 角度「0〜180(°)」に換算し、変数「angle」に格納することで角度指定値として使用しています。
7.まとめ
「RCサーボ」制御ライブラリ「ESP32Servo」を使用したサーボモータの制御方法について紹介しました。
一般的な回転モーターが電圧を加えると回転し続けるのに対して「RCサーボ」は電圧とは別に角度を指定する制御信号も与える必要があり、制御信号にはパルス状の電圧信号によって動作角度を制御することができます。
動作角度はパルス状の電圧波形の電圧が高い状態のパルス幅の時間で制御され、サーボモーター毎に「最小角度〜最大角度」に対応する「パルス幅時間μsの範囲」が決められています。
パルス状の電圧波形で制御する方法を「パルス幅変調(Pulse Width Modulation)制御」略して「PWM制御」と言います。
「RCサーボ」の制御には「PWM制御」の理解が必要ですが、ライブラリを使用することで、動作角度を指定するだけで簡単に制御することができます。
ライブラリを使用するための設定は、制御信号パルスの「周波数」と「出力端子番号」「パルス幅時間μsの最小値と最大値」の指定だけです。
今回はライブラリを使用した制御方法を紹介しましたが「PWM制御」の使い方さえ理解すれば、意外と簡単に制御できます。
これができると「RCサーボ」への理解もより深まりますし、使用するマイコンボードやプログラミング言語が変わっても制御することができるようになると思います。
「PWM制御」とライブラリを使用しない「RCサーボ」の制御方法については、以下のリンクで詳しく紹介しています。
コメント