R_Castleのアイコン画像
R_Castle 2020年02月18日作成 (2020年02月20日更新)
セットアップや使用方法 セットアップや使用方法 閲覧数 16381
R_Castle 2020年02月18日作成 (2020年02月20日更新) セットアップや使用方法 セットアップや使用方法 閲覧数 16381

ラジコンサーボモーターをArduinoで動かしてみる(その1)

今回はArduinoUnoで、ラジコンサーボモーターを動かすことについてご紹介します。
まずは基礎知識編として、応用的な使い方については記事を分けて行きたいと思います。

「サーボモーター」とは

電子工作やホビーロボットを製作している人の間ではサーボ、又はサーボモーターと言えばラジオコントロール機器の制御で使う製品の事を指します。四角い箱上の一面から回転する軸が出ている形状をした製品が多いです。
サーボモーターの例
元々の目的が無線操縦の模型に組み込む事を前提に作られていますので、普通のモーターに比べて独特の形状をしています。
基本的な形状のサーボモータ
簡単な信号で回転する角度を制御する事が出来るので、ラジオコントロールのかじ取りや走行用のモーターや小型のエンジンといった動力のスロットルコントロール等に利用されるほか、マイコンボードに多数接続して簡易的なロボットの関節として利用する事が出来ます。
尚、産業用のAC/DCサーボモーターと呼ばれるモーターとは制御方式が異なりますのであくまでも商品名もしくはある種類のホビーモーターの総称として覚えておいた方が良いでしょう。
最近ではホビーロボット専用のサーボモーターも発売されていますが、これらは少々複雑な通信制御が必要になりますので、後日改めて解説したいと考えています。今回は一般的なラジオコントロール機器に用いられている信号制御方式で作られているサーボモーターについて記述していきます。

サーボモーターからは3本の電線がひとまとめになってコネクタがついているケーブルが出ています。その色は各社様々なのですが、基本的なルールとして

黒(又は暗い色):GND(電源のマイナス)
赤(又は赤色系の色):Vin(電源のプラス)
それ以外の色:制御用信号線

となっています。このコネクタにそれぞれの電源、信号線を接続すれば制御する事が可能になります。
コネクタの例

サーボモーターの制御方法について

図に、基本的なラジオコントロール機器の制御信号について図示しました。
制御信号の周期と角度の関係

周期20ミリ秒、つまり1秒間に50回の信号をサーボモーターに送るのですが、この時1周期の間にどのくらいの時間信号をONにしているか?でサーボモーターの角度を決めることが出来ます。
こういった制御手法を「PWM(Pulse Width modulation)制御」と呼びます。

ちょっと強引ですが、Arduinoマイコンボードに1個のサーボモーターを接続して動かしてみましょう。

テスト用サーボ接続図
サーボモーターは動作に大きな電流を必要とします。
複数のモーターをマイコンボードに直接接続すると故障の原因となりますので注意してください。

信号のON/OFF時間を直接指示し、サーボモーターに制御命令として出力してみます。
サーボモーターを接続した状態

digitalWrite命令での直接制御

int motorPin = 5; void setup() { pinMode(motorPin, OUTPUT); } void loop() { digitalWrite(motorPin, HIGH); delayMicroseconds(1250); // ここに角度に該当する値を入れる。 digitalWrite(motorPin, LOW); delay(20); }

モーター1個だけであればこういったやり方から拡張していっても制御できますが、複数のモーターを動作させる場合や他の処理も加えたプログラムにしようとすると、この方法では制御周期が乱れて満足にコントロール出来なくなります。

幸いにもArduino SDKには複数のサーボモーターを制御することが出来る専用のライブラリと制御命令が用意されています。専用命令によるプログラムは最後に記述しますのでしばらくお待ちください。
また、いちばん右端を0度、信号の長さが長くなる毎に反時計回りに回転して行き左端180度まで信号を送る事が出来ますが、不用意な力が外からサーボモーターに加わっても制御不能になる事がない様、通常の製品では20度から160度くらいまでの範囲で動作する様に制御して使用する事をお勧めします。

サーボモーター選定のポイント

上記の様に電気信号で簡単に角度を指定して固定する事が出来るサーボモーターですので、簡単なギミックから本格的なロボットまで色々応用する事が出来ます。
その中身は沢山の歯車がかみ合って動いている小さなギアボックスが入っています。この歯車の内容でサーボモーターから取り出せる力の大きさや動作する速度が定められています。
サーボモーターの構造例
出典:双葉電子工業(株)製品紹介サイト

動作する力は「トルク」と呼ばれています。通常は回転モーメントの事を指し[N・m(ニュートン・メートル)]が用いられますが、そんな大きな力はサーボモーターからは出せませんので、メーカーが定めるカタログなどでは[kgf・cm]で表現されています。
例えば5[kgf・cm]のトルクを持っている、のであれば、軸の中心から1cmの長さのアームで5kgfの物体を動かすことが出来る事を意味しています。
トルクやモーメント等については垂直方向か水平方向か、摩擦はあるのか?など
厳密な解説を始めてしまうと物理の授業になってしまうので、別の機会に改めて説明したいと思います。

つまり、サーボモーターのトルクとアーム先端で動かせる物体の重さの関係を簡単な関係式で示すと

[動かせる重さ]=[サーボモーターのトルク]÷[アームの長さ]

という事になります。先の5[kgf・cm]のトルクを持ったサーボモーターに2cmの長さのアームを付けた場合、アーム先端で動かすことが出来る物体の質量は5÷2=2.5kgfと、長さに反比例して小さくなって行く事が分かります。
次に重要なのが動作電圧です。サーボモーターの多くは4.8V又は6.0Vで動作する様に作られており、ロボット専用の物になると更に大きな電源が必要になります。また、動作時に必要となる電流量も非常に大きなものになりますので、複数のサーボを動かすというのであればマイコンとは別のバッテリーなど電源を用意する必要があります。
さらに制御の都合上、ほとんどのサーボモーターはマイコンの制御信号で動作速度を直接コントロールする事が出来ません。メーカーのカタログなどをチェックして、あらかじめ必要な動作速度を満たしているモデルを選定する場合もあります。

Arduino SDK サーボモーター制御命令

Arduino SDKで用意されているサーボモーター制御コマンドについて説明します。

手順1:ヘッダーファイルの読み込み

#include <Servo.h>

ヘッダーファイルの読み込みを宣言したら、制御するサーボモーターのプログラム中での名前を宣言します。

手順2:プログラム中での名前を宣言

Servo servo;

次に、接続されているデジタルポートをサーボ制御用に宣言します。

手順3:サーボ制御用ポートの宣言

servo.attach(5);

Arduinoの種類によって制御できるサーボモーターの数、ポート番号は異なります。

繰り返しループ内で、位置決めしたい角度を指定します。

手順4:角度命令を出力する

servo.write(90);

プログラムに書くと以下の様になります。

SDKライブラリを用いたサーボモーター制御プログラム例

/*****************************************************************/ #include <Servo.h> // サーボ制御のライブラリを読み込みます。 Servo servo; // 制御するサーボ名を定義します。 void setup() { servo.attach(5); // 5番ピンの出力をサーボ制御用に宣言します。 } void loop() { servo.write(90); // 90度(ニュートラル) delay(1000); servo.write(30); // 30度(左に傾く) delay(1000); servo.write(90); // 90度(ニュートラル) delay(1000); servo.write(150); // 150度(右に傾く) delay(1000); } /*****************************************************************/

このプログラムを実行すると、デジタルポート5番に接続されたサーボモーターが1秒おきに90度→30度→90度→150度→90度・・・と傾く動作を繰り返します。

それでは、以前テストした光センサーを追加して、読み取った明るさをサーボモーターの傾きで示すプログラムを書いてみたいと思います。
ブレッドボードを使って、以下の様な回路を組み立てています。
光センサーとサーボモーターの接続図

光センサーの値を角度に変換してサーボモーターを動かすプログラム

#include <Servo.h> // サーボ制御のライブラリを読み込みます。Servo servo; // 制御するサーボ名を定義します。 void setup() { servo.attach(5); // 5番ピンの出力をサーボ制御用に宣言します。 } ​ void loop() { int cds = analogRead(0); // map関数で光センサの読み取り値600~1024の範囲を0~180の値に割り当てます。 int deg = map(cds, 600, 1024, 0, 180); ​ servo.write(deg); delay(1000); }

実際に動作させてみました。
ブレッドボードに配線した回路

光センサーの周りが明るい=読み取られる値が小さいと、サーボモーターへの指令値も小さくなり右回りになりました。
明るいと時計回り

反対に光センサーの周りが暗い=読み取られる値が大きいと、サーボモーターへの指令値は大きくなり左回りに動作しました。
暗いと反時計回り

通常の回転し続けるモーターと違ってサーボモーターを制御できる様になると、こういった角度や位置を制御する事が可能になるので電子工作で動かすことが出来るアイデアの幅が更に広がると思います。

次回は応用編として、複数のサーボモーターを制御する際の工夫や工作例などを紹介したいと思います。

ログインしてコメントを投稿する