YAMAHA アカデミックパック Processingでシリアル通信する(Java)



ポート名の調べ方

```java:serial_list

import processing.serial.*;

println(Serial.list()); 

```



１：調べたポート名を"hogehoge"に入力
２：グローバル変数の「linear」「angular」に好きな値を入力
３：「a」を押すとRequestCommand
４：「b」を押すとWriteReadCommand＝動き出す
５：「c」を押すと停止する

```java:YAMAHA_AcademicPack

import processing.serial.*;

Serial Port;

//電動車椅子の速度・角速度
float linear = 0.2; //速度[km/h](-5.6~5.6)
float angular; //角速度[km/h]

//配列の宣言
byte[] data1;  //RequestCommand
byte[] data2; //WriteReadCommand

//その他
int CheckSum1; //RequestCommand
int CheckSum2; //WriteReadCommand

boolean mode;
boolean status1 = false; //RequestCommand
boolean status2 = false; //WriteReadCommand


//電動車椅子の情報
float Perimeter = 1.18; //タイヤ周長[m]
float Gear_Ratio = 12.64; //ギア比[-]
float Distance = 0.24; //電動車椅子の中心から車輪までの距離[m]
float Turning_Radius =0.0; //電動車椅子の旋回半径[m]

//右のタイヤの回転数・速度
float rpm_right; //電動車椅子の右のタイヤの回転数[rpm]
float velocity_right; //電動車椅子の右のタイヤの速度[km/h]
float Velocity_right; //電動車椅子の右のタイヤの速度[m/s]

//左のタイヤの回転数・速度
float rpm_left; //電動車椅子の左のタイヤの回転数[rpm]
float velocity_left; //電動車椅子の左のタイヤの速度[km/h]
float Velocity_left; //電動車椅子の左のタイヤの速度[m/s]

//角速度
float Angular = angular/3.6; //角速度[m/s]


//速度（受信）
int RightSpeed;
int LeftSpeed;

void setup() {
  size(1000, 1000);

  //通信パラメータ
  //Serial(parent, portName, baudRate, parity, dataBits, stopBits)
  Port = new Serial(this, "/dev/tty.usbserial-AI0639FT", 38400, 'E', 8, 1) ;

  //配列の作成
  data1 = new byte[15];
  data2 = new byte[23];


  //配列の割当
  //RequestCommand
  //BaseFrame
  data1[0] = 0x01;  //ヘッダ
  data1[1] = 0x08;  //ソースアドレス
  data1[2] = 0x03;  //ディスティネーションアドレス 
  data1[3] = 0x01;  //通信番号
  data1[4] = 0x68; //コマンド
  data1[5] = 0x08;  //データ長
  //Data
  data1[6] = 0x01;  //モード（アカデミックモード＝01h）
  data1[7] = 0x00;  //
  data1[8] = 0x00;  //
  data1[9] = 0x00;  //
  data1[10] = 0x00; //タイムアウト（無効＝00h）
  data1[11] = 0x00; //
  data1[12] = 0x00; // 
  data1[13] = 0x00; //
  //CheckSum
  for (int i = 1; i <14; i++)
  {
    CheckSum1 += (int)data1[i];
  }
  data1[14] = (byte)CheckSum1; //CheckSum（これまでの数値の和の下位１バイト）
}


void draw() {
  background(0, 0, 0);

  if (status2 == true) {

    
    if (keyPressed) 
  {
    if (key == 'c')
    {
      linear = 0;
      angular = 0;
    }
  }


    if (angular == 0) { //角速度がゼロの場合 
      Turning_Radius =0.0; //旋回半径をゼロに指定する
      //速度から回転数への変換（右のタイヤ）
      rpm_right = (1000*linear*Gear_Ratio)/(60*Perimeter); 
      //速度から回転数への変換（左のタイヤ）
      rpm_left =  (1000*linear*Gear_Ratio)/(60*Perimeter);
    } else
    { //角速度がゼロ以外の場合
      Turning_Radius = linear/angular; //旋回半径を求める
      //速度から回転数への変換（右のタイヤ）
      velocity_right =(Turning_Radius + Distance)*(Angular);
      Velocity_right = velocity_right*3.6; //(m/s)から(km/h)への変換
      rpm_right = (1000*Velocity_right*Gear_Ratio)/(60*Perimeter);
      //速度から回転数への変換（左のタイヤ）
      velocity_left =(Turning_Radius - Distance)*(Angular); 
      Velocity_left = velocity_left*3.6; //(m/s)から(km/h)への変換
      rpm_left = (1000*Velocity_left*Gear_Ratio)/(60*Perimeter);
    }



    //WriteReadCommand
    //BaseFrame
    data2[0] = 0x01;  //ヘッダ
    data2[1] = 0x08;  //ソースアドレス
    data2[2] = 0x03;  //ディスティネーションアドレス 
    data2[3] = 0x01;  //通信番号
    data2[4] = 0x69; //コマンド
    data2[5] = 0x10;  //データ長
    //Data
    data2[6] = 0x02;  //ユニット有効指示（モータ回転指示値＝02h）
    data2[7] = 0x00;  //
    data2[8] = 0x00;  //JS
    data2[9] = 0x00;  //JS
    data2[10] = 0x00; //JS
    data2[11] = 0x00; //JS
    data2[12] = (byte)((int)rpm_right & 0x00FF); //右モーター回転指示（下位バイト） (-1000rpm~1000rpm)
    data2[13] = (byte)(((int)rpm_right & 0xFF00)>>8); //右モーター回転指示（上位バイト） (-1000rpm~1000rpm)
    data2[14] = (byte)((int)rpm_left & 0x00FF); //左モーター回転指示（下位バイト） (-1000rpm~1000rpm)
    data2[15] = (byte)(((int)rpm_left & 0xFF00)>>8); //左モーター回転指示（上位バイト） (-1000rpm~1000rpm)
    data2[16] = 0x00; //
    data2[17] = 0x00; //
    data2[18] = 0x00; //
    data2[19] = 0x00; // 
    data2[20] = 0x00; //
    data2[21] = 0x00; //

    //CheckSum
    CheckSum2=0;
    for (int i = 1; i <22; i++)
    {
      CheckSum2 += (int)data2[i];
    }
    data2[22] = (byte)(CheckSum2 & 0x00FF); //CheckSum（これまでの数値の和の下位１バイト）
    Port.write(data2); //WriteReadCommand 送信
  }
}




void keyPressed() {
  if (key=='a') { //RequestCommand起動
    Port.write(data1); //RequestCommnad 送信
    println(data1);
    status1=true;
  }
  if (key=='b') { //WriteReadCommand起動
    status2 = true; 
    status1 = false;
  }
  
}




void serialEvent(Serial Port) {

  //RequestCommand 受信
  if (status1 == true) {
    byte[] inBuffer = new byte[15]; //配列の宣言、作成
    while (Port.available() > 0) { //データが送られている間は
      inBuffer =Port.readBytes(); //ここに割当る
      println(inBuffer); //送られたデータを見たい
    }
  }

  //WriteReadCommand 受信
  if (status2 == true) {
    byte[] inBuffer2 = new byte[23]; //配列の宣言、作成 //15個来るはず
    while (Port.available() ==23) { //データが送られている間は
      inBuffer2 =Port.readBytes(); //ここに割当る
      Port.readBytes(inBuffer2);
      println(inBuffer2); //送られたデータを見たい

      //TimeStamp
      int lowerTime = Byte.toUnsignedInt(inBuffer2[6]);//byteからintへ
      int upperTime =Byte.toUnsignedInt(inBuffer2[7]);//byteからintへ
      int timeStamp = (upperTime <<8)+lowerTime; //下位バイトと上位バイトをガッチャンこ（0~65535)(10ms単位)
      textSize(24);
      fill(255, 255, 255);
      text("TimeStamp="+timeStamp+"ms", 100, 100);

      //Right
      int lowerRight = Byte.toUnsignedInt(inBuffer2[8]); //byteからintへ
      int upperRight = Byte.toUnsignedInt(inBuffer2[9]);//byteからintへ  　
      int rpmRight = (upperRight <<8)+lowerRight; //下位バイトと上位バイトをガッチャンこ（-1000rpm~1000rpm)
      textSize(24);
      fill(255, 255, 255);
      text("rpm_Right="+rpmRight+"rpm", 100, 200);
      float RightSpeed = rpmRight * 60/1000*Perimeter/Gear_Ratio;
      textSize(24);
      fill(255, 255, 255);
      text("speed_Right="+RightSpeed+"km/h", 100, 300);

      //Left
      int lowerLeft = Byte.toUnsignedInt(inBuffer2[10]); //byteからintへ
      int upperLeft = Byte.toUnsignedInt(inBuffer2[11]);//byteからintへ  　
      int rpmLeft = (upperLeft <<8)+lowerLeft; //下位バイトと上位バイトをガッチャンこ（-1000rpm~1000rpm)
      textSize(24);
      fill(255, 255, 255);
      text("rpm_Left="+rpmLeft+"rpm", 100, 400);
      float LeftSpeed = rpmLeft * 60/1000*Perimeter/Gear_Ratio;
      textSize(24);
      fill(255, 255, 255);
      text("speed_Left="+LeftSpeed+"km/h", 100, 500);

      //Battery
      int lowerBattery= inBuffer2[12]; //byteからintへ
      int upperBattery = inBuffer2[13];//byteからintへ  　
      int BatteryCurrent = (upperBattery <<8)+lowerBattery; //下位バイトと上位バイトをガッチャンこ（0%~100%)
      println("BatteryCurrent="+"0."+BatteryCurrent+"A");
      int Battery = Byte.toUnsignedInt(inBuffer2[14]);
      textSize(24);
      fill(255, 255, 255);
      text("Battery="+Battery+"%", 100, 600);
    }
  }
}

```