サーボモーターについて、ここではラジコンカーのステアリング等の制御に使用される「RCサーボ」についての使い方を詳しく紹介します。
使い方についてはM5Stack社製のESP32系マイコンボード「ATOM LITE」を使って、ライブラリを使用しない簡単な制御方法をサンプルプログラムを使用して紹介します。
ライブラリ「ESP 32Servo」を使用した制御方法は以下のリンクで詳しく紹介しています。
ESP32系マイコンボード「ATOM LITE」のPWM出力は分解能が最大16bitあるため分解能の低い(8bit)「Arduino UNO」等より、細かい角度で滑らかな動作で制御することができます。
「ATOM LITE」に「サーボ」を接続してサンプルプログラムを書き込むだけで動作確認できます。
「ATOM LITE」については以下のリンクで詳しく紹介しています。
「RCサーボ」を使用したラジコンの作り方も、以下のリンクで詳しく紹介しています。
1.サーボモーター(RCサーボ)とは
2.RCサーボの動作原理
・角度(0°〜180°)制御用「SG90 」
・回転(360°)速度制御用 M5Stack社製「Servo Kit 360」
3.RCサーボの制御方法
4.サンプルプログラム(コピペ)
5.サンプルプログラムの詳細
6.準備するものと接続方法
・角度(0°〜180°)制御用「SG90 」
・回転(360°)速度制御用 M5Stack社製「Servo Kit 360」
7.まとめ
1.サーボモーター(RCサーボ)とは
「サーボモーター」とは、電圧を加えたら回転し続けるモーターとは違い、角度や、回転速度を指定することで、指定した通りに動作しその状態を保持しようとするモーターです。
内部にモーターの回転部の位置や回転速度を検知するためのセンサが内蔵されており、このセンサの情報を元に角度や回転数を制御しています。
今回紹介するものは主にラジコン(Radio Control)カーのステアリング等の駆動部に使われているため「RCサーボ」と呼ばれているものです。
「RCサーボ」には内部にモーターや制御回路、位置検出センサ、ギヤが内蔵され、コンパクトなケースに収まっています。
2.RCサーボの動作原理
「RCサーボ」の動作原理について、角度を制御するRCサーボの「SG90」と、回転速度を制御する「M5Stack」社製の「360°回転サーボ(Servo Kit 360° LEGO-compatible)」を例に紹介します。
一般的な回転モーターが電圧を加えると回転し続けるのに対して「RCサーボ」は電圧を加えただけでは動作しません、動作させるには動作角度や回転速度を指定する制御信号も与える必要があります。
・角度(0°〜180°)制御用「SG90 」
以下が「SG90(正規品)」の外観写真です。
動作角度は0°〜180°で、コネクタの配線は3本あり「赤:電源[+]、茶:GND[0V]、黄:制御信号」です。サーボによって配線色は異なる場合もあるため使用する前にデータシート等でよく確認しましょう。
正規品との見分け方は以下になります。
上写真の左が正規品で右がコピー品です。
正規品には「Tower pro」の表示があります。
写真では分かりにくいですが、内部モータのピニオンギヤが正規品は金属、コピー品は樹脂です。
本体の表示銘板にも違いがあります。
左が正規品、右がコピー品です。正規品の方が文字が太くて、やや丸みのある文字で見やすいです。
同じメーカーの正規品ですが、360°回転サーボの「SG90-HV」には「Tower pro」の表示はありませんでした。
表示が無い分ピニオンギヤが金属製なのがよく分かります。
制御方法
制御信号にはパルス状の電圧信号を与えます。このようなパルス状の電圧波形で制御する方法を「パルス幅変調(Pulse Width Modulation)制御」略して「PWM制御」と言います。
「RCサーボ」の動作角度は、制御信号としてこのパルス状の電圧波形の中で「電圧が高い状態のパルス幅の時間(Duty比)」を指定することで角度が制御でき「SG90」では以下のような仕様になっています。
制御信号 パルス幅時間 | RCサーボ 制御角度 |
---|---|
0.5ms 〜 2.4ms | 0°〜 180° |
「PWM制御」の使い方については以下のリンクで詳しく紹介しています。
実際の動作は下図のようになります。
パルス幅時間が「0.5ms」の時に動作角度「0°」、「2.4ms」の時に「180°」、中間の動作角度はパルス幅時間の比率で指定され、真ん中のパルス幅時間の「1.45ms」にすると動作角度は「90°」になります。
・回転(360°)速度制御用 M5Stack社製「Servo Kit 360」
以下が「M5Stack」社製の「360°回転サーボ(Servo Kit 360° LEGO-compatible)」の外観写真です。
「ATYPE」と「BTYPE」の2個セットで、左右対象のブラケットが取り付けられており、左右の車輪として使用するのに便利です。
他にもLEGOブロックと組み合わせられるプーリーのような「車輪」と「リフトアーム」「コネクターペグ」、LEGOの車輪軸とサーボの軸を接続するための「アクスルコネクタ」、3Pコネクタをグローブコネクタに変換できる「変換基板」が付属しています。
回転速度は5Vで約100r/min(無負荷実測)で、コネクタの配線は3本あり「SG90 」と同様に「赤:電源[+]、茶:GND[0V]、黄:制御信号」です。
制御方法
制御信号は「SG90」と同様にパルス状の電圧信号を与えて「PWM制御」で制御します。
「360°回転サーボ」の回転速度は、制御信号としてパルス状の電圧波形の中で「電圧が高い状態のパルス幅の時間(Duty比)」を指定することで正転、停止、逆転が制御でき、以下のような仕様になっています。
制御信号 パルス幅時間 | RCサーボ 制御角度 |
---|---|
0.5ms 〜 1.5ms | 正回転(最高速) 〜 停止 |
1.5ms 〜 2.5ms | 停止 〜 逆回転(最高速) |
実際の動作は下図のようになります。
パルス幅時間が「0.5ms」の時に「正回転最高速」、「2.5ms」の時に「逆回転最高速」、真ん中のパルス幅時間の「1.5ms」にすると「停止」します。
3.RCサーボの制御方法
「PWM制御」を使用した「RCサーボ」の制御方法について紹介します。
制御方法については角度制御用サーボ「SG90 」を例に紹介します。
「PWM制御」については以下のリンクで詳しく紹介しています。
角度制御用サーボ「SG90 」の仕様は以下のようになります。
項目 | 仕様 |
---|---|
PWM周期 | 20ms(50Hz) |
PWM制御信号パルス幅時間 | 0.5ms 〜 2.4ms |
動作角度 | 0° 〜 180° |
ストール(ロック)トルク | 1.8kgf・cm(4.8V) |
移動速度 | 60°/0.1s(4.8V) |
動作電圧 | 4.8V(5V) |
デッドバンド(不感帯) | 1μs |
下図はPWM出力信号波形の1周期(20ms)分の波形です。
上の波形が動作角度0°の時、下の波形が動作角度180°の時の波形で、その間にPWM出力のDuty比の値を記入しています。
図中矢印下の「duty_min」や「duty_max」はサンプルプログラムで使用している「変数名」です。
PWM出力波形の1周期の中で、動作させたいサーボの動作角度に応じて「制御信号へのパルス幅時間」を「Duty比」で指定します。
指定可能な「Duty値」は「bit数(分解能)」で決まり、下表のようになります。
表を見ると「bit数」が1〜4bitの時は「PWM周波数」の最小値が50Hz以上で、20ms(1000ms/50Hz)周期の波形が出力できないため、制御不可であることがわかります。
5bitでは制御は可能ですが、指定できるDuty値が1〜3のため3段階の角度調整しかできません。
6bitでは6段階、7bitでは12段階となります。
滑らかな角度制御を行うには「bit数(分解能)」を大きく設定しましょう。
4.サンプルプログラム(コピペ)
プログラムは以下に準備しましたので「コピペ」して書き込んでください。
※コピーは下コード(黒枠)内の右上角にある小さなアイコンのクリックでもできます。
#include <M5Atom.h>
//FastLED(CRGB構造体)設定
CRGB dispColor(uint8_t r, uint8_t g, uint8_t b) {
return (CRGB)((r << 16) | (g << 8) | b);
}
// 端子割り付け
#define ADC_PIN 32 // アナログ入力端子
// 変数設定
float setting[16][5]; // チャンネル[0〜15]ごとの[周波数, bit数, 0゜パルス時間ms, 最大角度パルス時間ms, 最大動作角度]格納配列
float ad_val; // アナログ入力値
float ad_angle; // 角度換算用
/******************* PWM出力、サーボ仕様設定関数 *******************/
void servo_set(int pin, int channel, float freq, float bit_num, float time_min, float time_max, float angle_max) {
// サーボ設定値をチャンネルごとの配列に格納
setting[channel][0] = freq; // 周波数
setting[channel][1] = bit_num; // bit数
setting[channel][2] = time_min; // 0゜パルス時間ms
setting[channel][3] = time_max; // 最大角度パルス時間ms
setting[channel][4] = angle_max; // 最大動作角度
// PWM設定
pinMode(pin, OUTPUT); // PWM用ピンを出力設定
ledcSetup(channel, freq, bit_num); // PWM設定(チャンネル, 周波数, ビット数)
ledcAttachPin(pin, channel); // PWMチャンネル割り当て(ピン番号, チャンネル)
}
/******************* サーボ動作実行関数 *******************/
void servo(int channel, float angle) {
float resolution; // 分解能
float period; // 周期ms
float duty_min; // 0゜Duty計算値
float duty_max; // 最大角度Duty計算値
float duty_active; // 動作範囲のDuty計算値
int duty_value; // PWM出力Duty値(High状態)※整数型として小数点以下切り捨て
float read_angle; // PWM出力Duty値からの角度換算
// サーボ定数算出
resolution = pow(2, setting[channel][1]); // 分解能(2のbit数乗)
period = 1000 / setting[channel][0]; // 周期(1000ms / 周波数)
duty_min = (resolution / period) * (setting[channel][2]); // 0゜Duty計算値((分解能/周期)*0゜パルス時間μs)
duty_max = (resolution / period) * (setting[channel][3]); // 最大角度Duty計算値((分解能/周期)*最大角度パルス時間μs)
duty_active = duty_max - duty_min; // 動作範囲のDuty計算値
duty_value = (angle * (duty_active / setting[channel][4])) + duty_min; // 角度指定値(浮動小数点数) → PWM出力Duty値(整数)換算
if (duty_value <= duty_min) { // PWM出力Duty値が0゜Duty計算値以下なら
duty_value = duty_min + 1; // PWM出力Duty値+1
}
// PWM出力実行
ledcWrite(channel, duty_value); // 指定したチャンネルにDuty値を指定してPWM出力実行
read_angle = (ledcRead(channel) - duty_min) * setting[channel][4] / duty_active; // PWM出力Duty値を取得して角度に換算
// シリアル出力(delay()時間を長くしてから必要に応じて有効にする)
// Serial.printf("angle : %.1f ledcRead : %d duty_min : %.1f Freq : %.1f\n", read_angle, ledcRead(channel), duty_min, ledcReadFreq(channel)); // シリアル出力
}
// 初期設定 -----------------------------------------
void setup() {
M5.begin(false, false, true); // 本体初期化(UART, I2C, LED)
Serial .begin (9600); // シリアル出力初期設定
pinMode(ADC_PIN, ANALOG); // アナログ入力端子設定
M5.dis.drawpix(0, dispColor(0, 50, 50)); // LED点灯
// PWM出力、サーボ仕様設定(サーボごとに使用する端子、チャンネル等を設定)
// PWM出力のチャンネルは 0,1/ 2,3/ 4,5/ 6,7/ 8,9/ 10,11 /12,13 /14,15でペア ※周波数と分解能はペアで同じにする必要があります。
// (出力端子, チャンネル, 周波数, bit数, 0゜パルス時間ms, 最大角度パルス時間ms, 最大動作角度)
servo_set(25, 1, 50, 12, 0.5, 2.4, 180); // チャンネル1:PWM出力、サーボ仕様設定関数呼び出し
servo_set(21, 2, 50, 12, 0.5, 2.4, 180); // チャンネル2:PWM出力、サーボ仕様設定関数呼び出し
}
// メイン -------------------------------------------
void loop() {
M5.update(); //本体ボタン状態更新
if (M5.Btn.isPressed()) { // ボタンが押されていたら角度指定で動作
servo(1, 60); // チャンネル1:サーボ動作実行関数呼び出し(チャンネル, 角度値)
servo(2, 60); // チャンネル2:サーボ動作実行関数呼び出し(チャンネル, 角度値)
delay(300); // 動作完了待ち
} else { // ボタンが押されてなければボリュームで角度調整
ad_val = analogRead(ADC_PIN); // アナログ入力値(0〜4095)を取得
ad_angle = ad_val * 180.0 / 4096.0; // アナログ値 (0〜4095)→ 角度(最大動作角度)換算
servo(1, ad_angle); // チャンネル1:サーボ動作実行関数呼び出し(チャンネル, 角度値)
// ad_angle = 180 - (ad_val * 180 / 4096); // 2個の回転サーボを互いに違う方向に回転させたい時有効にする
servo(2, ad_angle); // チャンネル2:サーボ動作実行関数呼び出し(チャンネル, 角度値)
delay(10); // 遅延時間
}
}
5.サンプルプログラムの詳細
サンプルプログラムの動作について紹介します。
サンプルプログラムではPWM制御とサーボの設定を行う「servo_set()」、サーボ動作を実行する「servo()」を関数として準備しています。
14行目 〜 25行目が「servo_set()」関数です。
この関数は初期設定内の 64,65行目から引数を指定して呼び出されます。
引数には以下の内容を指定します。
出力端子:PWM制御に使用する出力端子(サーボの制御信号に接続)番号を指定
チャンネル:PWM出力タイミングを生成するチャンネルで 0〜15の中から指定
16個のチャンネルは 0/1 、2/3 〜 12/13、14/15 でペアになっており、
各ペアで周波数とbit数(分解能)は同じに設定する必要があります。
周波数:PWM出力周波数を設定(サーボの周波数(周期)に合わせる)
bit数:PWM周期を分割する分解能をbit数(1〜16)で指定
0°パルス時間ms:サーボ動作角度0°の時の制御信号パルス時間をmsで指定
最大角度動作時間ms:サーボ動作角度が最大の時の制御信号パルス時間をmsで指定
最大動作角度:サーボの最大動作角度を指定
指定した引数は「servo_set()」関数内で 9行目で宣言した2次元配列「setting」に格納します。
2次元配列「setting」は1〜16の「チャンネル」を1次要素として、残りの引数を2次要素として格納します。
続けて 22行目 〜 24行目でPWM制御の設定を行います。
ここでチャンネルごとに各サーボの仕様に合わせたPWM制御の設定を行っています。
27行目 〜 46行目がサーボ動作を実行する関数「servo()」です。
この関数は 72, 73行目または 78, 80行目から引数を指定して呼び出されます。
引数には以下の内容を指定します。
チャンネル:動作させたいサーボが接続されているチャンネルを指定
角度の値:動作させたいサーボの動作角度(0°〜最大動作角度)の値を指定
27行目からの「servo()」関数内では、指定された「チャンネル」ごとに2次元配列「setting」から各サーボの設定値を取り出して、指定された「角度の値」からPWM出力波形の「Duty値」を算出します。
続けて 48行目の「ledcWrite()」で「チャンネル」と「Duty値」を指定してPWM出力を実行することでサーボの動作を制御することができます。
「配列」や「条件分岐」等「C言語」については以下のリンクで詳しく紹介しています。
6.準備するものと接続方法
準備するものは「ATOM LITE」を中心に以下のようになります。
「ATOM LITE」の使用が初めてで、開発環境から準備したい方は以下のリンクで始め方を詳しく紹介しています。
「ATOM LITE」や「ボリューム」については以下のリンクで詳しく紹介しています。
・角度(0°〜180°)制御用「SG90 」
「ATOM LITE」に「SG90 」を接続したものが以下の写真になります。
接続方法は下の配線図のようになります。
部品はどれもAmazonで購入できて、全部購入しても¥3,000程で揃います。
「ジャンパー線」と「ピンヘッダー」はどちらかあれば大丈夫です。
「ジャンパー線」はごちゃごちゃするので個人的には好きではありませんが、自由度は高いので動作確認用としては確実に接続できて便利です。
「ピンヘッダーL型」はコンパクトに端子が引き出せて配線がすっきりするのでよく使います。
ただ、このままでは「ATOM LITE」側の挿さりが浅いため、動作確認用として考えて使用してください。
・回転(360°)速度制御用 M5Stack社製「Servo Kit 360」
「ATOM LITE」にM5Stack社製の「360°回転サーボ(Servo Kit 360° LEGO-compatible)」を接続したものが以下写真のようになります。
「5V」と「G(0V)」を分岐させるためだけに「ブレッドボード」を使用しています。
「G21」と「G25」にはサーボの制御信号端子を接続します。白色配線を挿していますが使用するジャンパー線によっては違う色になります。
Servo Kit付属の変換コネクタは「D-S」「V-V」「G-G」が繋がっていて、「C」には何も繋がっていません。
接続方法は下の配線図のようになります。
ハンダ付けが苦にならない方は「L型ピンヘッダー(2段)」を加工して、下写真のようにするとシンプルに接続できます。
ピンヘッダー2段目の「5V」と「G(0V)」用端子を短く切って押し込んで下の段の端子とハンダ付けします。
「G21」には2段目の端子を曲げてハンダ付けします。不要な端子はラジオペンチ等で引き抜くことができます。
サーボのコネクタを2段重ねにしてコンパクトに接続することができます。
「360°回転サーボ(Servo Kit 360° LEGO-compatible)」のキットではなく、単体で「360°回転サーボ」が必要な場合は、下写真の「SG90-HV」がほぼ同じように使用できます。
断定はできませんが同じもののように思います。
タイヤやギヤ等を軸に取り付けたい場合は付属の「ブラケットA,B」やLEGOの「リフトアーム」「コネクターペグ」「アクスルコネクタ」が便利です。
「アクスルコネクタ」は単品で売ってれば買いたいですが見つかりません・・・誰か売ってるの見かけたら教えてください(汗)
上写真が「アクスルコネクタ」です。
「M5Stack社」の公式ページで付属品として「Axcel Connector」と記載されています。
単品売りはしてないようなので残念です・・・
付属品のLEGOのリフトアームに組み付ければ、LEGOのタイヤを取り付けられます。
タイヤをつけるとこんな感じでこのまま駆動部として使えます。
(こうなるとなんかテンション上がります♪)
LEGO テクニックシリーズのパーツ購入は楽天かyahoo!の「LEGOブロック専門店 ブリッカーズ」で、コネクターペグでも1個から購入できておすすめです。
その他の部品はAmazonで購入することができます。
7.まとめ
「RCサーボ」の使い方について紹介しました。
「RCサーボ」はラジコンのステアリング部等の駆動部に使用され、内部にモーターの回転部の位置や回転速度を検知するためのセンサが内蔵されており、このセンサの情報を元に角度や回転数を制御しています。他にも制御回路やギヤが内蔵され、コンパクトなケースに収まっています。
一般的な回転モーターが電圧を加えると回転し続けるのに対して「RCサーボ」は電圧を加えただけでは動作しません、動作させるには動作角度や回転速度を指定する制御信号も与える必要があります。
制御信号にはパルス状の電圧信号を与えます。このようなパルス状の電圧波形で制御する方法を「パルス幅変調(Pulse Width Modulation)制御」略して「PWM制御」と言います。
「PWM制御」については別記事で詳しく紹介していますのでそちらで確認してみてください。
制御信号として「PWM制御」の電圧波形の中で「電圧が高い状態のパルス幅の時間(Duty比)」を指定することで、角度を制御するサーボでは角度を、回転(360°)サーボでは正転速度、停止、逆転速度を制御できます。
動作確認には「M5Stack社」製のマイコンボード「ATOM LITE」が便利です。
「Arduino UNO」等よりも分解能が高く、より滑らかな動作で制御することができます。
ライブラリ「ESP32servo」でも制御できますが「PWM制御」の使い方がわかればライブラリを使用しない方がシンプルで応用が効き、種類の違うサーボの個別の設定も容易に行うことができます。
安価で入手できる「RCサーボ」と「ATOM LITE」の組み合わせは「PWM制御」を理解するのに最適です。
これが理解できるとDCモータの速度制御や位置決め制御を行う回転サーボ、ステッピングモータ、インバータによるモーター速度制御等の理解をするときに役に立ちます。
当ブログでは、今回使用した「SG90」と「360°回転サーボ(Servo Kit 360° LEGO-compatible)」を使用したラジコンの製作を紹介予定です。
次回は、まずラジコンを「Bluetooth」通信でコントロールするためのコントローラー製作のために、ジョイスティックでサーボを制御する方法を紹介したいと思います。
コメント