2017年3月1日水曜日

部活で始めるArduino③「サーボモータ応用編」

サーボモータをより精密に制御する

サーボモータの応用編です。
今回は前回1°単位で制御したサーボモータをもっと精密に制御します。

サーボモータはマイコンなどから送られてくるパルスのパルスの幅で角度を決めています。
たとえば前回使ったSG90はこちらによれば
・動作角度 180°
・動作パルス幅 500~2400μs
だそうです。どういうことかというと
※波形は誇張してあります

上の図のようにサーボモータの角度が、ある決められたパルスの幅、つまりONとOFFが高速で切り替わるうちのONの時間に対応しているということです。
500~2400μsなので-90°は500μs、90°は2400μs、0°は真ん中の1450μsに対応します。
前回やった方法では、入力された角度に対応した波形を自動で出してくれていた、というわけです。

サーボモータをより精密に動かすにはこのパルス幅を直接指定してやります。
2400-500=1900 なのでおよそ0.1°の精度が期待できます(実際はもう少し誤差が出ます)。


作業に移りましょう。
パルス幅を直接指定する関数は
  writeMicroseconds(r)  //rはμs単位のパルス幅
です。前回同様Servo.hの中の一つです。

では前回のプログラムを上の関数を使うよう書き換えてみましょう。

-45° → 500(=-90°) + 1900(=180°) × 45°/180° ≒ 975(μs)
45° → 500(=-90°) + 1900(=180°) × 135°/180° ≒  1925(μs)

となるので

#include<Servo.h>       //サーボモータのライブラリをインクルード
Servo servo1;            //servo1というServoオブジェクトを作る

//最初に一度だけ実行
void setup() {
    servo1.attach(9);   //servo1が刺さっているのは9番ピン
}

//setupの後無限ループ
void loop() {
    servo1.writeMicroseconds(975);    //置き換えたところ
    delay(1000);          //1000ms(ミリ秒)=1秒待つ
    servo1.writeMicroseconds(1925);  //置き換えたところ
    delay(2000);         //2000ms(ミリ秒)=2秒待つ
                             //「{」のところに戻る
}

赤くなっているところが置き換えたところです。
同じように動作すると思いますが違いが分かりませんね。

この関数は角度を直接指定する用途より、ある角度からある角度に動かす用途に使った方が輝きます。下のプログラムで確かめてみます。

#include<Servo.h>       //サーボモータのライブラリをインクルード
Servo servo1;            //servo1というServoオブジェクトを作る
int angle,pulse;     //angle : °単位の角度、pulse : パルスの幅//最初に一度だけ実行
void setup() {
    servo1.attach(9);   //servo1が刺さっているのは9番ピン
    angle = 0;     //angleを0にする
    pulse = 0;     //pulseを0にする
}

//setupの後無限ループ
void loop() {
    for(angle=45;angle<=135;angle++){
    servo1.write(angle);
    delay(10);     //10ms待つ
    }     //servo1をangle度にしてangleに1足す処理をangleが135になるまで繰り返す
    delay(10000);    //1秒待つ
    for(pulse=1925;pulse>=975;pulse--){
    servo1.writeMicroseconds(pulse);
    delay(1);     //1ms待つ
    }     //servo1にpulseを出力してpulseから1引く処理をpulseが975になるまで繰り返す
    delay(2000);         //2000ms(ミリ秒)=2秒待つ
                             //「void loop() {」のところに戻る
}

最初が角度単位の移動、次がパルス幅を基準とした移動です。
より滑らかでトルクも高くなることが分かっていただけると思います。

今回はこんな感じです。
正直プログラムに組み込むのはちょっと面倒な代物ですが、カメラをサーボで動かしたりする用途にはいいかもしれません。

次回はシリアル通信機能を紹介します。