2012年3月4日日曜日

加速度センサーに合わせて3Dオブジェクトを揺らす

シリアル通信で255より大きい数字を送る のエントリーでArduinoは準備OKになりました。

Processing側のスケッチのデータの受信部分は
ArduinoとProcessingの連携2:大きな値を送信する、データの流れを視覚化する
加速度を求める部分は
3軸加速度センサーを使ってみる
のスケッチをProcessing側で使います。



センサーの動きに合わせてウィンドウ内の箱を上下左右に動くようにします。
センサーのXYZ軸とPCのXYZ軸は一致しないので、動きが合うようにY軸、Z軸、正負を逆にしてます。

自分用に手を加えた結果が下のスケッチ。
◆Processingのスケッチ
import processing.serial.*;

int NUM = 3;          //アナログ入力の数を指定
float V=5.0;                //電源電圧
float VD=4.890;             //実際にセンサーに供給されている電源電圧
float kando = 1.0;          //出力振幅(感度)Vdd/5(V/g)
float x,y,z;

Serial myPort;
int[] val = new int[NUM];  //Serialより読み込んだデータを格納する配列

void setup() {
  size(400,400,P3D);
  String portName = Serial.list()[1];    //ポートの名前を取得
  myPort = new Serial(this, portName, 9600);
}

void draw() {
  background(0);
  translate(width/2 +x, height/2 +z, -500 +y);
  rotateX(radians(-15));
  rotateY(radians(-15));
  rotateZ(radians(0));
  fill(255,75,75);
  box(150,150,150);
  myPort.write(255);   //通信開始の合図
}

//シリアル入力を検出した際に発生するイベント
void serialEvent(Serial p) {
  //もし、バッファーにアナログ入力の数の2倍(上位8bitと下位8bit)あれば
  if(myPort.available() > NUM * 2 - 1) {
    for(int i=0; i<NUM; i++) {
      int val_high = myPort.read();       //上位8bitを取得
      int val_low = myPort.read();        //下位8bitを取得
      val[i] = (val_high<<8)+ val_low;    //2つのbit列を合成
      if(i == NUM-1) {                    //もし全ての入力を処理したら

        x=val[0]*VD/1024;
        y=val[1]*VD/1024;
        z=val[2]*VD/1024;
   
        float xv=x-VD/2.0 -0.07;        //加速度に対応した電圧を求める
        float yv=y-VD/2.0 +0.02;        //3軸、補正してます
        float zv=z-VD/2.0 -0.11;
     
        float xg=xv/(kando*VD/V);        //電圧から加速度を求める
        float yg=yv/(kando*VD/V);
        float zg=zv/(kando*VD/V)-1.0;
     
        x=xg*-300;                     //加速度を移動量に変換
        y=yg*300;
        z=zg*300;
        myPort.write(255);                //読み込み完了の合図を送る
      }
    }
  }
}



次のエントリーではオブジェクトを傾けたいと思います。

環境:Arduino Uno R3、Arduino 1.0、Processing 1.5.1



0 件のコメント:

コメントを投稿