LoginSignup
3
1

More than 3 years have passed since last update.

Unity - Arduino間でBluetooth Serial通信をするとUnity終了時にSerialを閉じるのに失敗する

Posted at

はじめに

生じた問題はタイトルのとおりです.
Arduino(私の場合はTeensy4.0)からUnityにシリアルでデータを送る際,有線だとUnity終了時にSerialPort.Close()が機能したのですが,Bluetooth経由だと機能せずにアプリケーション終了後もゾンビスレッドが爆誕してしまった.といった感じです

環境

Windows10
Unity2019.4.3f1

マイコン : Teensy4.0
Bluetoothモジュール : BlueSMiRF Gold

使用スクリプト

Unity-Arduino間のシリアル通信であまりにも有名なスクリプトを用いています.
今回は一昔前のThreadを使用したものではなく,Taskを用いた以下の記事を参考にさせていただいています.

[Unity]非同期処理(Task)の利用例(UDP送受信,SerialPortのRead)

原因

なぜSerialPort.Close()が失敗するかですが,それはSerialPort.Close()を呼ぶタイミングでも裏で走っている以下のReadAsync()タスク内のSerialPort.ReadLine()が終了していないからです.
もっと正確に言うと,SerialPort.Readline()でシリアルからの入力を待ち続けてしまっており,そのときにSerial.Close()を呼び出してしまうとこのTaskがゾンビTaskになってアプリケーション終了後も走り続けてしまう,といった感じでしょうか...(Unityを落とせばこのTaskも消えます.)

SerialHandler.cs
async Task ReadAsync()
    {
        await Task.Run(() => {
            while (isRunning && serialPort != null && serialPort.IsOpen)
            {
                try
                {
                    string message = serialPort.ReadLine();
                    OnDataReceived.Invoke(message);
                }
                catch (System.Exception e)
                {
                    Debug.LogWarning(e.Message);
                }
            }
        });
    }

何も入力がないときはSerialPort.ReadLine()が終了するように,Serial.Open()時に以下のようにタイムアウトを設定してあげましょう.(タイムアウトの間隔はアプリに合わせて変えてあげましょう.)

SerialHandler.cs
    public void Open(string portName)
    {
        if(isRunning) return;

        currentPortName = portName;

        serialPort = new SerialPort(portName, baudRate, Parity.None, 8, StopBits.One);

        // ここでReadのタイムアウトを設定する.
        serialPort.ReadTimeout = 500; //[milliseconds]

        serialPort.Open();
        isRunning = true;
    }

これでSerial.Close()がちゃんと機能し,ゾンビタスクが爆誕することはなくなりました.

なぜ有線だとこのタイムアウトの設定がいらなくてBluetoothだと必要なのかが未だにわかっていませんが,とりあえず良しとします.

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1