12.Arduinoでサーボモータをコントロールする

今回はクムクムについている7個のサーボモーターを例に、Arduinoからサーボモーターをコントロールする方法について説明します。

サーボモーターとは

サーボモータは、電気を流してただひたすら回転をさせるプラモデルや扇風機などに使われているモーターとは異なり、命令によって角度や速度などをを自由にコントロールすることができます。

クムクムロボットでのモーターの役目は、ある角度でピタリととめることによって、その回転角度を利用して手や足の動きを作っていることです。

サーボモーターも実は中をばらしてしまえば、普通の回転するモーターでできているのですが、このモータにーに回転を絶妙にコントロールするためのギアーや、現在角度を知るためのパーツなどによってつくられています。

黒…GNDライン
赤…電源
橙…回転角度(パルス)

PCやマイコンなどから与えられた回転角度(パルス)によってモータは電子基板を通してある一定の時間モーターを回転させる。
回転と同時に、モータシャフトの回転に合わせてポテンションメータも回転し、その値を電子基板内に取り込み指定パルスとの調合をとって回転角度の段階でモーターの回転をとても小さな量で行ったり来たりさせることで停止状態を作る。

クムクムのモーター

クムクムに使用しているモーターは0~180度の回転角度を持っていて、与えるパルスは500~2500という仕様になっています。

つまりソフトウエアーで500か2500というパルスを与えると、0度か180度の位置に回り切ります。
90度で止めたければ1500というパルスを与えれば真ん中でピッタリ止まってくれます。

Arduinoから動かすための配線

サーボモータとArduinoとの接続は下記のようにします。

この配線のポイントは、モーターの電源をArduinoの5Vのピンから取らずに、電池から直接取っているところです。

サーボモータの回転には相当な電力が必要です。
この電力をArduinoの5Vから取ってしまうと、Arduinoにすごく負担がかかって、ArduinoのCPUが壊れてしまいます。また、万が一動いたとしても、電源を一杯食われてしまうため、突然変な動きになってしまったりする可能性が大きいのです。

かならず、モーターは別電源でとります。
また、ラジコン用のサーボモーターは4.5V以上で動作するものが多いので、ここでは電池4本(6V)で動作させるようにしています。

※サーボモーターは電力を必要とするため、本当はニッケル水素(ENELOOP)などのパワーのある電池を使うことをお勧めします。
※電池のマイナス側は必ずArduinoのGNDと接続してください。(Arduinoの4番からのパルスは、ArduinoのGNDと4番をモーターに接続して初めて動作します。

クムクムのサーボモーターのArduinoピン番号

クムクムには7個のサーボモーターが接続でき、それぞれ、腕や足、顔のモーターをコントロールしています。そのモーターをArduinoのピン番号と合わせてみると下記のようになります。

Arduino Servoライブラリーでプログラミング

Arduinoの標準ライブラリーには、サーボモータを簡単に扱える Servoクラスが用意されています。そのサーボクラスを使用すると、簡単にサーボモーターを好きな角度まで回転させて止めることができます。

下記はクムクムで制御する場合のソースコードの最も単純な角度指定でのサンプルです。

下記のソースコードでクムクム専用部分としては、void MortorPowerという関数です。
クムクムでは、モータを回転させるためには、まず、電源からモーターへ電源を供給するスイッチONにする必要があるため、この関数で7番ピンの信号をHIGHにしています。


//*************************************************************************************
// サーボモータを動かすサンプル
//
// モータへの電源はコントロールポート(11)のLOW HIGH でできる
//*************************************************************************************

#include <Serve.h>

//左足首(0),左足付け根(1),左手(2),右足首(3),右足付け根(4),右手(5),顔(6)
Servo SV[7];
#define SV_PIN_MOTOR_TOP 4 // ServoMotorPIN D4~D10
#define SV_PLS_MIN 600 // サーボモータ最小パルス値 (要調整)
#define SV_PLS_MAX 2440 // サーボモータ最大パルス値 (要調整)
#define PIN_MOTOR_POWER 11 // ピンアサイン(外部電源)
#define SV_COUNT 7
#define MORTOR_ON HIGH
#define MORTOR_OFF LOW


//---------------------------------------------------------------------------
// アタッチ処理
//---------------------------------------------------------------------------
void AttachSV()
{
    for(int i = 0; i < SV_COUNT; i++) {
        SV[i].attach(SV_PIN_MOTOR_TOP + i);
    }
}
//---------------------------------------------------------------------------
// デタッチ処理
//---------------------------------------------------------------------------
void DetachSV()
{
    for(int i = 0; i < SV_COUNT; i++) {
        SV[i].detach();
    }
}
//---------------------------------------------------------------------------
//モーターへの電源供給
//---------------------------------------------------------------------------
void MortorPower(int sw)
{
    digitalWrite(PIN_MOTOR_POWER,sw) ; 
}

//---------------------------------------------------------------------------
//セットアップ
//---------------------------------------------------------------------------
void setup() 
{
    pinMode(PIN_MOTOR_POWER,OUTPUT) ;    
    MortorPower(MORTOR_OFF) ;
    AttachSV() ;
}
//---------------------------------------------------------------------------
//モータを動かしてみる
//---------------------------------------------------------------------------
void loop() 
{
    MortorPower(MORTOR_ON) ;                    //モーターへ電源供給   
    for( int i = 0; i< SV_COUNT; i++ ){         //最小から最大まで動かす
        SV[i].write(0);                         //移動
    }
    delay(1000);
    for( int i = 0; i< SV_COUNT; i++ ){         //最小から最大まで動かす
        SV[i].write(90);                         //移動
    }
    delay(1000);
}

細かく角度を指定したい場合

上記のプログラムでは0~180度まで1度単位で角度を指定しています。
実は、ArduinoのServoクラスではパルス幅(500~2500)で回転位置を指定することもできる関数が用意されています。
この関数を使えば、これまで0~180までの分解能で指定していた角度が、500~2500までの2000の幅で角度を指定することができるため、より細かい制御ができます。

パルス値を指定して attach

attach関数にはパルス値を指定することができます。

SV[i].attach(SV_PIN_MOTOR_TOP + i);をSV[i].attach(SV_PIN_MOTOR_TOP + i,SV_PLS_MIN,SV_PLS_MAX);としてアタッチの時に最小パルス値と最大パルス値を与える。

角度指定をパルスで指定する

writeMicroseconds関数はパルス値で回転角度を決めることができます。

SV[i].write(0);や SV[i].write(90);としている0や90といった角度指定を別命令、SV[i].writeMicroseconds(1500);に書き換えてパルスで指定する。

 

コメント