UnityでArduinoにシリアル通信を送る

![SS 192.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/a41cd967-f549-8677-1efa-2e99bf69518d.png) 　UnityからArduinoにシリアルを送ってLチカする

#やること
UnityでArduinoにシリアル通信を送るテストを行います。
前回記事 [UnityでArduinoからシリアル通信を受け取る](https://qiita.com/Ninagawa_Izumi/items/f6595dcf788dd316be8a) の逆です。


#主な参考URL
- [UnityとArduinoをシリアル通信](https://qiita.com/yjiro0403/items/54e9518b5624c0030531)

#環境
- Unity Hub
- Unity 2018.4.28f1
- Arduino

#事前準備
[UnityでArduinoからシリアル通信を受け取る](https://qiita.com/Ninagawa_Izumi/items/f6595dcf788dd316be8a)
↑に書かれている内容を実施し、動く状態にしておきます。
この記事では上記との差分のみを説明します。

#Arduinoの準備

Arduino側のスクリプトはシンプルに下記のようにします。
"1"という文字を受信したらLEDを点灯するようにします。

```C:Arduino
#define LED_PIN 13 //LEDのピン番号。13は内蔵LED。
char data;

void setup() {
  Serial.begin(115200);
  pinMode(LED_PIN, OUTPUT);
}

void loop()
{
  if ( Serial.available()  > 0 ) {   // 受信データがあるか？
    data = Serial.read();            // 1文字だけ読み込む
    if (data == 0x31) { //文字コード0x31、つまり"1"を受信したらLEDを光らせる。
      digitalWrite(LED_PIN, HIGH);
      delay(200);
      digitalWrite(LED_PIN, LOW);
    }
  }
}
```
Arduinoに書き込んだら準備は終了です。


#Unityの設定変更
Unityから一定間隔で"1"という文字をシリアルで送ろうと思います。

FixedUpdateメソッドを使えば、Unityのフレーム更新毎の命令とは別に、コードを一定間隔で実行する設定ができます。先にその「一定間隔」を設定しておきます。

「Edit」→「Project Setting」→「Time」より、
Fixed Timestepを0.001(1/1000)に設定しておきます。（環境によっては0.01などでもかまいません。デフォルトは0.02のようです。）
![SS 574.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/ebf8d529-c919-ec9d-3d0d-97d623bb1cd9.png)

#Unityのスクリプト設定
UnityからArduinoへシリアルを送信するスクリプトを作成します。

#### SerialSend.cs を作成します。
C#のスクリプトを作成し、ファイル名を「SerialReceive」にします。
スクリプトは下記のようにします。

```C#:SerialReceive.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SerialSend : MonoBehaviour
{
    //SerialHandler.cのクラス
    public SerialHandler serialHandler;
    int i = 0;

    void FixedUpdate() //ここは0.001秒ごとに実行される
    {
        i = i + 1;   //iを加算していって1秒ごとに"1"のシリアル送信を実行
        if (i > 999) //
        {
            serialHandler.Write("1");
            i = 0;
        }
    }
}
```
終わったらセーブします。

#スクリプトをアタッチする
作成したスクリプトが実行できるようにします。

「Assets」内にあるスクリプト「SerialSend」をヒエラルキーウィンドウのオブジェクト「Serial_Test」にドラッグ＆ドロップでアタッチします。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/e07515b5-990e-8f2e-1899-1ee053657901.png" width = 300>
ヒエラルキーウィンドウの「Serial_Test」をクリックし、右のインスペクターウィンドウを確認します。

インスペクターの「SerialSend(Script)」の「SerialHandler」のボックスに、ヒエラルキーウィンドウの「Serial_Test」をドラッグアンドドロップしてアサインします。

また、インスペクターの**「SerialRead」のチェックを外して無効**にします。

これで準備が完了です。


#実行
Unityの再生ボタンを押し、実行します。
うまくいけばArduinoのLEDが1秒間隔で点滅します。

#終了方法
Unityの再生停止ボタンを押した後、**Arduino側のリセットボタンを押します。(超重要)**
Arduino側のリセットボタンを押さないと、Unityがシリアルの送受信プロセスを終了することができず、カーソルがクルクル回り続け終了できません。
今回はテストなのでそのままでもよいですが、いざ実用となった際にはコードにタイムアウト処理やクローズ処理を入れるなど、もう一手間必要でしょう。


#おわりに
これで最低限のUnity→Arduino間のシリアル通信もできるようになりました。
双方向通信やスピード調整、長いデータのやりとりなどに細かなTipsが必要のようなので、そのあたりを調べていきます。

- 前回記事：[UnityでArduinoからシリアル通信を受け取る](https://qiita.com/Ninagawa_Izumi/items/f6595dcf788dd316be8a)

# 参考
下記のサイトを参考にさせていただきました。ありがとうございました。

- [SerialPort または Uniduino を使った Unity と Arduino を連携させる方法調べてみた](https://tips.hecomi.com/entry/2014/07/28/023525)
- [Unity - Arduino間でBluetooth Serial通信をするとUnity終了時にSerialを閉じるのに失敗する ](https://qiita.com/AceZeami/items/54410f7f9c4bd1d78bba)
- [UnityとArduinoをシリアル通信](https://qiita.com/yjiro0403/items/54e9518b5624c0030531)
- [Unityでシリアル通信する際に試したこと](https://qiita.com/kaz0414/items/30e23e29770471a5f347)
- [Arduino+Unity（シリアル通信）するときの手順メモ ](https://note.com/ke_takahashi/n/n12ba947ec88c)