サーボモータを制御する①

今日の目標は360°サーボがどうなってんのか理解することです。
OFとArduinoの連携を試したりしてたのですが、
サーボがどうやってOFとArduinoから角度を受け取っているのかなどがわからず、
サーボをうまく制御することが出来なかったので、初心にかえってみます。

【今日やりたいこと】
測距センサの値が一定以上になったら、
指定した角度までサーボを回転させ、停止させたい。

OFと連携させるとわけがわからなくなるので、Arduinoだけでやります。

【使用ツール】
Arduino 1.0.5
Arduino:UNO
サーボ:GWSサーボ S125-1T/2BB/F(フタバ)
センサー:シャープ測距モジュール GP2Y0A21YK

【参考】
Arduino サーボ制御…建築発明工作ゼミ2008
サーボモータ

【上記をざっと読んでみてわかったこと】
“サーボもDCモータ同様、Arduino基盤に対しては過電流となる恐れがあるので、別電源を用意したほうが無難”
これ知りませんでした!危ない…一つくらいなら平気でしょう、とのこと。

パルス幅がわかるとなんとかなるような気がしてきました。
サーボによって受け入れるパルス幅が異なるらしい。
最大パルス幅を、
第2章 RCサーボの性能を調べる…サンおやじ工作室
を参考に実測してみる。

電源を切って手で回してみたところ…
回り続けました。

360°連続OKのやつだからなんでしょうが、、、
仕様書読んでもよくわからないので
とりあえず動かしてみよう!
ArduinoのServoライブラリを使ってます。

[cpp]
#include <Servo.h>
Servo servo;//サーボのインスタンス

void setup(){
Serial.begin(9600) ;

//サーボの信号線を3番ピンに接続
//(PWMピン以外のピンにも接続可)
servo.attach(9);
}

void loop(){
//サーボ出力
servo.writeMicroseconds(2400); //パルス幅値を代入:544~2400
delay(8000) ; //8秒間停止
servo.writeMicroseconds(544); //パルス幅値を代入:544~2400
delay(8000) ; //8秒間停止

// 上記プログラムでは、writeMicroseconds()を使うことで、
// 0~180度の範囲を544~2400の範囲の分解能で動かすことができます
// (180度の範囲を2400-544=1856分解能、約0.1度単位で角度を調節可能)。
// 上の場合はanalogRead()を使っているので、その精度に左右されます(つまり1024分解能)。
}

[/cpp]

このサーボのパルス幅がデフォルトと同じ544~2400なら、
2400を入力したときに、きれいに360°回転してくれるはず!なんですよね。
結果:
①2回転ちょいくらいしてすこしゆっくり動き出す
②突然逆回転を2回転ちょいくらいして何秒か止まってから①に戻る
という結果になりました。

ofでやってきた経験上、
このサーボは角度”0″を送るとゆっくり回転してしまうのと、
“180”以上を送ると止まるのがわかっているので、
544(=0)と2400(=180)がまずいのかな?と考えました。
[cpp]
servo.writeMicroseconds(2400); //パルス幅値を代入:544~2400
delay(8000) ; //8秒間停止
servo.writeMicroseconds(544); //パルス幅値を代入:544~2400
delay(8000) ; //8秒間停止
[/cpp]

を、下記のように変更。
[cpp]
servo.writeMicroseconds(2300); //パルス幅値を代入:544~2400
delay(8000) ; //8秒間停止
servo.writeMicroseconds(550); //パルス幅値を代入:544~2400
delay(8000) ; //8秒間停止
[/cpp]

結果:
あまり挙動は変わらなかった。

やっぱりパルス幅がわからないとダメなんですかね。
YAHOO!知恵袋によると
“交流といえばsin波形ですが、パルスといえば矩形波形です。
直流電流をスッチでオン・オフすれば、矩形波の電流が流れます。
1回転に1パルス発生させる場合、普通、1回転の1/100とかの
短い時間がオン状態になっています。つまり、パルス幅の短いものが
使われます。
パルス発生器の仕様をN[パルス/回転]としよう。

他方、サーボモータで移動する場合、移動距離は回転数に比例する
ように作ってある。その機構は色々な方法がありますが、
その仕様を M[m/回転」としよう。

そうすれば 1パルスあたりの移動量=M/N[m/回転] となる。”

らしいですが、よくわからない…
でも2400で2回転以上してしまうということは、その半分以下が360°になるのかも?

ということで!下記のように変更してみました。
[cpp]
#include <Servo.h>
Servo servo;//サーボのインスタンス

void setup(){
Serial.begin(9600) ;
servo.attach(9, 1000, 1200); //ピン番号,最小パルス幅,最大パルス幅
}

void loop(){
//サーボ出力
servo.writeMicroseconds(1200);
delay(8000) ;
servo.writeMicroseconds(1000);
delay(8000) ;
}

[/cpp]

結果:
①70°左回転→約8秒停止→②へ
②70°右回転→約8秒停止→①へ
微妙にゆっくり回る謎の挙動がなくなりました!
1200→1000の間(200)は、70°ということがわかりました。

ただ、最大最小のパルス幅を適当に決めた上での70°なので、
このサーボの最大最小パルス幅がわかった上で、それを入力したらまた変わるのかも。

今日はここまで!目標まで終わらなかったので、
明日に続くと思います。

– – – – – – – – – – – – – – –
2013.11.14 追記
Iさんがパルスについて調べて教えてくれました!

■パルスとは?

パルスモーターの軸をある角度回転させるための信号。
例)
信号が0.1秒24V出る→ある角度回って止まる
一回転が1000パルスだとしたら、その信号を1000回繰り返す
1秒で1000繰り返せば1秒で1回転。(1パルスは1/1000秒)

■パルス幅
信号の長さで、回る角度が決まるらしい?
例えば信号の長さが0.5のときは-n度、1のときは0度、1.5のときはn度とか。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください