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


 UnityからArduinoにシリアルを送ってLチカする

やること

UnityでArduinoにシリアル通信を送るテストを行います。
前回記事 UnityでArduinoからシリアル通信を受け取る の逆です。

主な参考URL

環境

  • Unity Hub
  • Unity 2018.4.28f1
  • Arduino

事前準備

UnityでArduinoからシリアル通信を受け取る
↑に書かれている内容を実施し、動く状態にしておきます。
この記事では上記との差分のみを説明します。

Arduinoの準備

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

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のようです。)

Unityのスクリプト設定

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

SerialSend.cs を作成します。

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

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」にドラッグ&ドロップでアタッチします。


ヒエラルキーウィンドウの「Serial_Test」をクリックし、右のインスペクターウィンドウを確認します。

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

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

これで準備が完了です。

実行

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

終了方法

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

おわりに

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

参考

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