サーボは、パルス出力の長さをArduinoなどで制御して、任意の角度に設定できるものです。
購入したサーボは、秋月電子 GWSサーボ 360°回転するタイプです。
GWSサーボ S125-1T/2BB/JRタイプ
http://akizukidenshi.com/catalog/g/gM-01723/
このサーボモータの上にwebカメラを設置し、一定時間ごとに角度を変えれば2つの植物に対して定点観測ができます。
一定時間ごとに撮影するのは、pcの時計を利用してprocessingでコントロールします(そのうちUPします)
サーボモータのコントロールはprocessingでシリアル通信をして動かしてみます。
processingからAruduinoにシリアル通信するときには、8ビット(0~255)の数値で送らなければならないので、その数値を何倍かさせてパルス信号のHIGH時間をコントロールしました。今回はだいたい7倍くらいかなと思い実行させてみました。
サーボとArduinoの接続は、サーボの赤をArduinoの5V、黒をGND、白をデジタルピンの3ピンに接続します。
processingのコード
//シリアルライブラリの取り込み
import processing.serial.*;
Serial port;
PFont font; //フォントの使用
//X座標の変数
int x=0;
void setup(){
font = loadFont("MS-Gothic-48.vlw");
//フォントを使用開始、サイズ:24
textFont(font,24);
size(255,100);
//シリアルポートの設定
port=new Serial(this,"COM5",9600);
}
void draw(){
background(100);
x=constrain(mouseX,0,255);
port.write(x);
port.read();
text(x,width/2,height/2);
}
Arduinoのコード
int val=0;
void setup(){
//パルス出力ピンの設定
//(デジタル出力なのでどのピンでも可)
pinMode(3,OUTPUT);
Serial.begin(9600);
}
void loop(){
//パルス:HIGHを出力
val = Serial.read()*7;//シリアル通信
digitalWrite(3,HIGH);
//パルス最小値を550としvalを代入
delayMicroseconds(val+550);
//パルス:LOWを出力
digitalWrite(3,LOW);
//HIGHの継続時間を差引いて周期を20000usに調整
delayMicroseconds(10000-(val+550));
delayMicroseconds(10000);
}
processingのプログラムを動かし、マウスを動かして、0~255の値を入れます。
マウスのX座標がシリアルでArduinoに送られパルス信号を作ります。
まず、0を入力してみました。
すると、0だとずっと回転してしまいます。
つぎに、255を入力すると1回転以上してある角度でとまります。
だいたい、15位である角度でとまるようになります。
これは、サーボモータの特性ではないかと考え、最低値が15以上になるようにしなければなりません。
いろいろ試してみるとだいたい155位で360°回転することが分かりました。
そこで、127という中間を中心に上下に振ってみます。
最低値:127-77=50
最大値:50+155=255
50~205でコントロールすると安定して動作します。
これで動かすとすると、50のときは、0度、180度のときは127、360度のときは205の数値を入れます。
これだと、分解能が155になり、数値1あたりは、360/155=2.32°ほど回転する計算になります。
例えば、30°の位置に回転させたいならば、30/2.32= 12.93
50+13=63 を入力すればいい計算になります。
ちょっと説明不足で分かりにくかったかもしれませんが、こんな感じでコントロールできます。
もし、いつも同じ角度で回転させることが決まっていればArduino側で設定してもよいかもしれません。そうすれば、もっと分解能が高く設定できます。 また、今回はパルスを生成する際に7倍しましたが、もっと小さな値にすれば、155以上の分解能は確保できそうです。
今回は、Arduinoでパルスを作りましたが、ライブラリを使ってもできるみたいです。
http://kousaku-kousaku.blogspot.com/2008/06/arduino.html
ちょっと、やってみましたが、うまくいかなかったので、だれか上手くいった人がいたら教えてください。
今後は、実際にwebカメラを一定場所に設置し、いよいよ植物の定点観測をしていく予定です。
niwaさんへ
返信削除サーボが振動してしまうのは、Arduino側のシリアル通信の部分かもしれません。Arduinoのソース内の
val = Serial.read()*7;//シリアル通信
の部分を以下のように置き換えてみて下さい。
if(Serial.available()>0){
val = Serial.read()*7;//シリアル通信
}
訂正前のソースは、非同期のシリアル通信なので、Arduino側はデータがまだ届いていなくてもSerial.read()でデータを読み込もうとしています。Arduinoは毎秒50回くらい読み込んでいますが、Processingの方はおそらくそれ以下の速度で送信してくるので、調整が必要になってきます。
訂正後は、Serial.available()を用いることで、Arduino側はProcessingからデータが送られてくる度に、データを読み込み、valに代入することになります。そうすることで、データが途切れないようになるので、動きも安定すると思います。試しにやってみて解消しなければ、また投稿/コメントして下さい。
実際にやってみると思うようにいかないものですね。
返信削除ここ数日はまってました。
kousakuさんアドバイスありがとうございます。
返信削除if(Serial.available()>0){
val = Serial.read()*7;//シリアル通信
}
でやってみたのですが、あまり変化はなかったようです。数値を変化させない時のサーボの状態は、多少振動があるものなのでしょうか?
ブッブッブッとその場で振動しています。
また、数値を変えた時にサーボが動き始めるのがすぐではなく、1秒くらいたってから反応する感じです。
これって、ちょっと遅いですよね?
今回やろうとしているのにはあまり反応速度は関係ないですけど、今後いろいろ問題になりそうですよね。
Arduinoの方の反応が遅いということは、バッファにProcessing側からのデータがたまっているということだと思います。ということは、Arduinoの速度よりもProcessingの送信速度の方が速いということかもしれません。
返信削除ひとつの解決方法としては、Processingの通信速度を少し遅らせるということになります。
例えばProcessingのvoid setup(){...}内に
frameRate(30);
を書き加えて、ループ速度(フレームレート)を毎秒30フレームに落としてトライしてみて下さい。
Arduinoは20ミリ秒のループなので毎秒50フレームになるはずです。非同期通信なので、データの送信側(Processing)が受信側(Arduino)より遅いほうが通信がうまくいくと思います。
そうでなければ同期通信にしてしまうかです。参考例は「Processing-Arduino シリアル通信4」
http://kousaku-kousaku.blogspot.com/2008/06/processing-arduino.html
にあります。
kousakuさんありがとうございます。
返信削除frameRate(30);
を追加したら、数字が変化したらすぐに反応するようになりました。
講義のときに、正確が細かくなるといっていた意味が分かってきたような気がします。通信っていろいろルールがあって大変ですね。