2007年06月07日

Arduino

Flashからサーボを動かす

前回の数値を送る仕組みを利用して、Flashからサーボをコントロールしてみる。

servo.jpg

ソースダウンロード

今回使ったサーボは、RB90
小型で、値段が手ごろ

サーボーは、PWMというパルスで、コントロールする。
20msの間に、0.5~2msのハイの間隔で、サーボの角度を指定する。
serbo_z.jpg
arduinoでPWMが使えるポートは、PWMと基盤に書いてある。
少し古いものだと、9~11の3ポートだけだったか、最近のものは、3,5,6も使えるようになっている。

arduinoソース
int sum;
const int KETAMAX = 4;        // 桁数
int keta;

int servoPin = 9;
int pulse = 1000;

void setup()
{
  pinMode(servoPin, OUTPUT);
  Serial.begin(9600);
  iniKeta();
}

void loop () {
  // データが来た
  if(Serial.available()>0){
    int val = Serial.read();
    if(val == 's'){          // データのはじめ
      iniKeta();
    }else{                  // 数値データ
      val -= 48;            // アスキー→数値に変換
      for(int i=1; i < keta; i++){  // 桁数を計算
        val *= 10;
      }
      sum += val;
      keta --;
      if(keta == 0){        // すべてのデータ受信終了
        pulse = constrain(sum, 500, 2450);  // オーバーフローする値を切り捨て
      }
    }
  }
  moveServo();
}

// サーボを動かす
void moveServo()
{
  digitalWrite(servoPin, HIGH);
  delayMicroseconds(pulse);
  digitalWrite(servoPin, LOW);
  delay(18);
}

// 最初の桁に戻る
void iniKeta(){
  keta = KETAMAX;
  sum = 0;
}

基本的には、前回と同じ。
違うところは、moveServo()で
ハイにあげて、pulseの時間を待った後、
ローに入れるという単純な仕組みで、PWMを生成している。

void moveServo()
{
  digitalWrite(servoPin, HIGH);
  delayMicroseconds(pulse);
  digitalWrite(servoPin, LOW);
  delay(18);
}

Flashのソース
フレームレート10で動作確認、早くしすぎるとサーボが遅くなる。

import Arduino;

var pwm;						// パルス値
var changFlg = false;		// 値が変わったか

// 環境に合わせて、ポートを設定する。
// COM1:5331、COM2:5332、COM3:5333、COM4:5334、COM5:5335、COM6:5336
var port:Number = 5334;

var arduino:Arduino = new Arduino(port);

// arduinoに送信
function sendData(data){
	arduino.send(data);
}

// スライダー設定
slider.setValue(0);
slider.setChangeHandler("onChangeScroll", this);

// スクロールバーの値が変わった
function  onChangeScroll(){
	var val = Math.round(slider.getValue());
	val *= 3;
	val += 500;
	var msg = "s";
	if(val < 10){
		msg += "000" + val;
	}else if(val < 100){
		msg += "00" + val;
	}else if(val < 1000){
		msg += "0" + val;
	}else{
		msg +=  val;
	}
	changFlg = true;
	txt.text = val;
	_root.pwm = msg;
}

// データが変わったときに送ると、送りすぎになるので、
// フレームレートごとに値が変化したときだけ送信
onEnterFrame = function(){
	if(pwm != undefined && changFlg){
		sendData(pwm);
		changFlg = false;
	}
}