Arduino

Arduinoを使ったサーボモータの動作

今まではArduinoを使ってLEDの点灯・消灯をコントロールする回路やプログラムを作成してきました。ここまで出来るようになると、実際に物体を走らせたり、動かしたくなりませんか?そこで、今回は物体を動かすのによく使用するサーボモータの使い方を確認します。

サーボモータとは

サーボモータとはサーボ機構において位置、速度等を制御する用途に使用するモーターのことを指します。(Wikipadia)工業的なモータではなく、ホビー用途のサーボモータは0°~180°等の可動域でモータが動作し、モータに付属するプラスチックの部品などで物体を動かします。

サーボモータはパルスを受信し、そのデューティ比で回転角を制御します。そのパルス幅は標準的なものだと1ms~2msになり、このパルス幅の比率を変化することによってサーボモータの可動を制御します。例えば、パルス幅が1msの場合は0°で2msだと180°といった具合です。ただし、サーボモータによっても個体差があるため、左記のように必ずしもなるわけではありません。そのため、校正(キャリブレーション)をして可動域を調整する必要があります。

SG90

今回使うサーボモータはSG90というサーボモータです。安価で割とメジャーなサーボモータだと思います。早速データシートを確認してみましょう。


データシートではGNDは茶色、電源は赤、出力線がオレンジとなっていますが、実物を見るとGNDは茶色、電源はオレンジ、出力線が黄色となっているかと思います。

sg90はデューティ比が0.5ms~2.4msであり、1周期は20msとなっています。すなわち、0.5msが0°で2.4msが180°となり、この比率を制御することによって回転角を制御します。(※個体差の校正は考えていません)

サーボモータを動かしてみる

サーボモータをArduinoで動かすには、それぞれを下図のようにジャンパー線で繋げばよいです。Arduinoの9番ピンとサーボモータの出力線、5Vと電源線、GND同士をつなぎます。


今回はサーボモータの仕組みを知るということをメインにしていますので、こんな簡単な回路(?)で十分です。

プログラムコード

ここではサーボモータを1°ずつ動かして180°まで行ったら折り返すプログラムを作ります。そのプログラムが以下となります。

const int SERV = 9;//servモータを9番ピン
const int CAL = 550;//校正用の値

void setup() {
// put your setup code here, to run once:
pinMode(SERV,OUTPUT);//servモータを出力モード
}

void loop() {
// put your main code here, to run repeatedly:

//0~180°
for(int i = 0; i <=180;i++) { rotation(i); } //180~0° for(int j = 180;j>0;j–)
{
rotation(j);
}

}

//サーボモータ回転
void rotation(int x){
digitalWrite(SERV,HIGH);
delayMicroseconds((x*10.5)+CAL);
digitalWrite(SERV,LOW);
delay(5);
}

サーボモータは動力となりますのでピンを出力モードで設定しています。

pinMode(SERV,OUTPUT);//servモータを出力モード

ここでのポイントはこのrotation関数(オリジナル関数)です。この関数の中でデューティ比を変化させ、所定の計算式で得たマイクロ秒だけ待機することによってサーボモータを任意の角度分だけ動かしています。

//サーボモータ回転
void rotation(int x){
digitalWrite(SERV,HIGH);
delayMicroseconds((x*10.5)+CAL);
digitalWrite(SERV,LOW);
delay(5);
}

digitalWrite関数でサーボモータにHIGHを出力した後にdelayMicroseconds関数で待機しています。これらが実際のパルス幅のONとなるところです。

計算式を簡単に説明します。sg90のデータシートを見て頂くとDuty Cycleが0.5ms~2.4msとなっています。すなわち500μs~2400μsがサーボモータの0°~180°の可動域になります。

つまり、1°のパルス幅は(2400-500)/180 = 約10.5となりますので、xを任意の角度とするとx*10.5がサーボモータの回転角になります。ただし、サーボモータは個体によって大きく差があります。その個体差を校正(キャリブレーション)することによって補っています。上記の計算式のCALがそれにあたります。

校正値を求めるにはこのコードのCALを大体500~600くらいの間で変更し、ちょうどいい具合の数値を探してください。

実行結果

動かしてみた結果が次の動画になります。

 

ライブラリを使ってサーボモータを動かしてみる

ここまでは、Duty Cycleのパルス幅を調整し、待機するマイクロ秒を計算式で求めて角度を変化させていました。実際にやってみるとお分かりだと思いますが、非常に手間で別のオリジナル関数を作るなど面倒くさいのが正直なところです。

そこで、Arduinoでは予めサーボモータを動かすためのライブラリが用意されており、インクルードしてあげれば簡単にサーボモータを動かすプログラムが作れるのです。

ライブラリを用意する

さて、ここからライブラリを使ってサーボモータを動かすプログラムを作っていくのですが、その前にライブラリを用意する必要があります。

下図のようにスケッチ -> ライブラリをインクルード -> Servo を選択します。

すると、”#include <Servo.h>”とプログラムの先頭に追加されますので、これで完了です。

プログラムコード

ライブラリを使ったプログラムは以下になります。

#include <Servo.h>

Servo srv; //サーボクラス
const int SRV = 9;//サーボモータを9番ピン
const int MAX = 180;//サーボモータの最大角度
const int MIN = 0;//サーボモータの最小角度

int angle = 0;//サーボモータに指示する角度

void setup() {
// put your setup code here, to run once:
srv.attach(SRV,500,2400);//サーボモータに9番ピンを指定
}

void loop() {
// put your main code here, to run repeatedly:

//0°~180°
for(int i = MIN; i <= MAX; i++)
{
srv.write(i);
delay(5);
}
//180°~0° for(int j = MAX; j > MIN; j–)
{
srv.write(j);
delay(5);
}

}

Servoライブラリではサーボモータのオブジェクトを作る必要がありますので、最初にクラス宣言をしています。

Servo srv; //サーボクラス

そして、次の関数ではどのピンに出力するかと0°及び180°のパルス幅の校正をしています。デフォルト値は0°で544μsで180°で2400μsとなります。

srv.attach(SRV,500,2400);//サーボモータに9番ピンを指定

角度を指定するにはSERVOクラスのwrite関数を使います。

srv.write(i);

実行結果

実行すると次の動画のように動きます。

まとめ

今回はArdudinoを使ってサーボモータの制御をしました。サーボモータはロボットアームにも使われるため、よく使う部品になるかと思います。サーボモータには個々に個体差があるため校正する必要はありますが、Arduinoでもライブラリが用意されているため簡単に使える代物となっています。

是非とも、サーボモータを使ってロボットアームでいろいろなことをやってみたいと思います。

参考書籍