概要
Arduino でサーボモータの角度制御を速度制御を行ってみました
環境
- Mac OS X 10.10.5
- Arduino UNO
- Arduino IDE 1.6.7
- サーボモータ SG90
配線
サーボモータから出ている線の
- 茶色 -> Arduino GND
- 赤色 -> Arduino 5v電源
- オレンジ色 -> Arduino GPIO 8 番
という具合に配線します
VarSpeedServo ライブラリをインポート
これ を使います
リリースページから最新版の zip をダウンロードし解凍します
2016/02/02 時点での最新版は v1.1.3 でした
https://github.com/netlabtoolkit/VarSpeedServo/releases/download/v1.1.3/VarSpeedServo.zip
Arduino IDE を起動して
スケッチ -> ライブラリをインクルード -> .ZIP形式のライブラリをインストール
を選択してください
ダウンロードした zip ライブラリを選択する画面になるので選択します
追加が完了すると「Library added to your libraries. Check “include library” menu」と IDE に表示されればライブラリのインポートは OK です
制御用スクリプト
サンプルコードは以下の通りです
#include <VarSpeedServo.h>
VarSpeedServo servo;
int pin = 8;
int deg = 0;
int speed = 50; // 1 - 255
void setup() {
servo.attach(pin);
Serial.begin(9600);
}
void move_servo(int deg) {
servo.write(deg, speed, true);
servo.detach();
}
int serialRead() {
char c[4];
for (int i = 0; i < 3; i++) {
c[i] = Serial.read();
if (c[i] == '\0') {
break;
}
}
return atoi(c);
}
void loop() {
move_servo(deg);
if (Serial.available() > 0) {
delay(10);
int input = serialRead();
if ( input >= 0 && input <= 180 ) {
Serial.println(input);
servo.attach(pin);
deg = input;
}
}
}
まず setup でサーボモータを制御するピンとシリアルモニタの初期化をします
loop でメイン処理に入ります
move_servo メソッドで引数に与えられた角度にサーボモータを動かします
その際に servo.write(deg, speed, true)
を使うことで角度を動かします
2 つ目の引数にサーボモータを動かすスピードを指定することができます
1 から 255 までの範囲で指定することができ、1 が低速で 255 が高速になります
プログラム内の speed という変数で速度を調整できます
最後の true はサーボモータが指定された角度に動くまで次の処理を待ちます
loop 処理内で常にシリアルの入力を受け付けています
シリアルに角度を入力すると入力された角度にサーボモータが動きます
最後に
今回は以上です
Arduino ではサーボモータを制御する標準のライブラリに Servo.h があります
これを使っても角度を動かすことはできますが、速度の制御は自分で実装する必要があります
やるとしたら Servo.write で角度を 1 ずつ変えてその度 delay で休ませる時間を調整する感じになると思います
たぶん、VarSpeedServo を使うほうが断然楽だと思います
初心者ですがこのスケッチでSG92Rを動かしました。speedを10にしてゆっくり回転させました。始めに高速で90度回転した後にスロー(speed10)で90度反転して停止しました。停止した位置がサーボモーターの機械的な原点0度とみていいのですか(電源offで手で回してみるとそれ以上回転しないのでギアの機械的停止位置のようです。始めに高速で90度近く回転しているようですがそのスケッチ(プログラム)はどれに該当するのでしょうか?
返信削除それからこの回転動作をずーっと繰り返す場合と設定した回数繰り返す場合のスケッチはどうなるのでしょうか?
追記: 信号線位置を8から9(PWM)に変更しても同じ動きですけどPWMに関係ないのですか?
全く初歩的な質問ですいません。メールアドレス: fuji255127@yahoo.co.jp
よろしくお願いいたします。
返信削除だいぶ昔の記事なので記憶も知識も薄いのですが、、、
返信削除> 停止した位置がサーボモーターの機械的な原点0度とみていいのですか
そうですねサーボモータは決められた範囲でのみ可動するので停止した位置が 0 度だと思って大丈夫かなと
> 始めに高速で90度近く回転しているようですがそのスケッチ(プログラム)はどれに該当するのでしょうか?
本記事のサンプルはサーボを回すためのライブラリを使っているのでそっち側で 0 度の位置に高速で戻す処理があるのかもしれないです
> それからこの回転動作をずーっと繰り返す場合と設定した回数繰り返す場合のスケッチはどうなるのでしょうか?
無限ループであれば loop の Serial.available() の部分をなくせば OK かなと思います
指定回数繰り返すのであればカウンタ用の変数を準備してあげてその回数に到達したら move_servo をコールしないようにすれば OK かなと
どうしてもダメってことであれば、Arduino 掘り起こしてこちらで試してみます、、、すぐできるかどうかわからんですが
早速の返信ありがとうございます。無限ループであれば loop のSerial.available() の部分は具体的にどこからどこまでを削除するのでしょうか。
返信削除if (Serial.available() > 0) を削除したところ動きは1回で止まりました。
何故か高速で反時計回りに回転する角度は90度でなく60度くらいに変化しています。
それから本記事のサンプルはサーボを回すためのライブラリを使っているのでそっち側で 0 度の位置に高速で戻す処理があるのかもしれないです
の意味がよくわかりません。すみません
> if (Serial.available() > 0) を削除したところ動きは1回で止まりました。
返信削除結局 PWM なので信号がうまく遅れてないんだと思います。delay(10); を長くしてみてはどうでしょうか
> 高速で戻す処理があるのかもしれないです の意味がよくわかりません。
本記事で紹介しているコード内に高速で戻す処理は実装していないはずです
なので、servo.attach などをコールした際にライブラリ (VarSpeedServo.h) 側でそういった処理をしている可能性がありそう
という意味です