マミさんの膝の上

主に、Unity・3D プリント・設計・解析のネタや、VR関連についてのメモ書きです。

UnityとArduinoのシリアル通信


Unity(3D)で、Arduinoとシリアル通信させた時の備忘録です。

・目的
 ・ 圧力センサーFSR402を使用して、指で押されたかどうかを判断したい

・ ArduionとFSR402の構成
  ・ 下記サイトを参考にしました。
  ・ http://processing.e2handai.jp/?p=84

・ 開発環境
  ・ Windows 8.0
  ・ Unity 4.5.0

・ Unity側の初期設定
  1.UnityでSerialPort使用時の設定
    Unityのメニューより、[Edit/Project Settings/Player] を選択し、[Optimaization]の[Api compatibility Level]を[.NET 2.0]に変更します。



  2.スクリプトの配置
     Unityに空のGameObjectを追加し、スクリプトを付与しておきます。
   



・ 使用する際の注意点
  1. Unity実行時に、Arduinoの開発環境を起動したままにしない!
     UnityとArduinoの開発環境が競合してしまい、 Unity実行時に[IOException: アクセスが拒否されました][InvalidOperationException: Specified port is not open.]といった感じで怒られます。
     Unityで書き込みやプレビューを実行していない時はエラーが出ない場合もありますが、Arduino側は閉じておいた方が無難かと思います。
(2014/08/26追記) シリアル通信を行うスクリプトを2つ以上のオブジェクトに配置してしまった場合も、Unity内で競合し[IOException: アクセスが拒否されました]が発生するケースがあります。

  2. Arduino側とUnity側の送受信タイミングを考える
    今回、Arduino側で100msのディレイを入れています。
    これはディレイ無しでArduinoを実行すると、Unityで読み取る際に大量に受信してしまい、結果的にセンサー値の読み取り結果が反映されるまでに非常に時間がかかるようになります。   

・ 実行結果
  ・ 押していない間はB、押している間はAのメッセージが表示されます。






・ Unity(C#) : ArduinoSerialIOScript.cs
 
using UnityEngine;
using System.Collections;
using System.IO.Ports;
using System.Threading;

public class ArduinoSerialIOScript : MonoBehaviour {

  SerialPort stream = new SerialPort("COM3", 9600);

  void Start () {
    OpenConnection ();
  }
  void Update () {
 
    string result="";
result = stream.ReadLine();
    Debug.Log (result);
 
  }

  void OnApplicationQuit(){
    stream.Close();
  }

  void OpenConnection() {
 
    if (stream != null) {

      if (stream.IsOpen) {
       stream.Close ();
       Debug.LogError ("Failed to open Serial Port, already open!");
  } else {
       stream.Open ();
        stream.ReadTimeout = 200;

        Debug.Log ("Open Serial port");     
}
    }
  }
}
Arduino
 
int sensorPin = A0; // select the input pin for the potentiometer

int ledPin = 13; // select the pin for the LED

int sensorValue = 0; // variable to store the value coming from the sensor

void setup() {

pinMode(ledPin, OUTPUT);

Serial.begin(9600);

}

void loop() {

// read the value from the sensor:

sensorValue = analogRead(sensorPin);

//Serial.println(sensorValue);

if(sensorValue > 300){

Serial.println("A");

} else {

Serial.println("B");
}

delay(100);

}