こんにちは、エンジニアのオオバです。

この辺りの文脈から最近micro:bitを触りだし、自分の子供と甥向けになにか作ってやろうと思っている次第です。

今回はSerialPortクラスを使ってUnity(C#)とmicro:bit間でシリアル通信しようとしたときの話です。

ちなみにSerialPortクラスを使用するためにはビルドセッティングで.NET 2.0 Subsetではなく、.NET 2.0にしておく必要があります。

Unityとmicro:bit間のシリアル通信におけるResource busyトラブル_0

以下がサンプルコードです。

micro:bit側シリアル通信送信JavaScriptコード

// Aボタンを押したらジャイロ情報を送信  
input.onButtonPressed(Button.A, () => {  
    let dx = input.acceleration(Dimension.X);  
    let dy = input.acceleration(Dimension.Y);  
    let dz = input.acceleration(Dimension.Z);  
    serial.writeLine("x,y,z : " + dx + "," + dy + "," + dz);  
})  

Unity側C#シリアル通信受信コード一部

var serial = new SerialPort(portName, baudRate, Parity.None, 8, StopBits.One);  
try  
{
    serial.Open();  
    serial.DtrEnable = true;  
    serial.RtsEnable = true;  
    serial.DiscardInBuffer();  
    serial.ReadTimeout = 5;  
}
catch (Exception e)  
{
    Debug.LogWarning(e.Message);  
}

C#側で以下の例外がスローされ、シリアルポートを開くことができないトラブルに見舞われました。

Resource busy

原因はscreenコマンドとバッティングしてたからだと思われます。

micro:bitでシリアル通信を実装することを調べていると、screenコマンドでシリアル通信を監視する周りの記事がヒットします。
ぼくもご多分に漏れずscreenを簡易デバッグ用として使用したのですが、これがトラブルの元になったようで、どうやら同時使用ができないようです。

ということでscreenのセッションをkillします。

screen kill PID  

※PIDはscreen -listで検索する

めでたくUnity側でSerialiPortを開くことができるようになりました。

余談

screenコマンドを初めて使用しましたが、結構特殊なオペレーションでしたが、こちらの記事に助けられました。

オススメ記事
検証環境
参考サイト