Unityからシリアルデバイスへ送信
↓
シリアルデバイスが動作
について書きます。
※受信については今回取り扱いません。
Unityからシリアルデバイスへの送信のみです!すみません。
##実行環境
・Unity 2019.1.8f1
・Serial Port Utility Pro(Unityアセット) https://portutility.com/ja/
・Windows10
##System.IO.Portsは使いません
・System.IO.Ports
「Unity シリアル通信」でググったら、一番いっぱい出てきました。
しかし、Unity5やWin10で使うには色々とエラー除去する必要があったり、
通信中にフリーズしてしまったりと、ややこしい感じでした。
もっと楽なのが出ていたので(下記)、そっちつかいます。
##Serial Port Utility Proとは?
Unity3Dで使える強力なシリアルポート通信ユーティリティ。
System.IO.PortsではWindowsしかできませんが、
これを使うとAndroid、Linux、MacOS、Windowsでシリアル通信可能に!!
有料は$78ですが、無料版もあります。
Free Version Limitations
※無料トライアルバージョンでは、以下制約つき
・いずれかのデバイスのデータ転送(送受信)が合計1MBまで使用可能です。
超過後は自動的に通信が切断されアプリケーションを再起動するまで使用できません。
・ Windows及びMacOSのみサポートされています。
・ 無料バージョンを使用したアプリケーションの配布はできません。
※ちなみに、日本の方が作られたアセットなので、
リファレンスも日本語で非常に取り入れやすかったです👍
##無料版の導入
https://portutility.com/ja/
アセットの公式サイトの、
少し下の方にある、無料版をダウンロード をクリックします。
.unitypackageがダウンロードされるので、
Unityを起動している状態でファイルを開きます。
インポートウィンドウが出てくるので
全て選択された状態でImportをクリック。
インポートしたアセットフォルダ>Scriptsフォルダ内に
SerialPortUtilityPro.csがあるので、
シーン上の好きなゲームオブジェクトにアタッチします。
以下のようなインスペクタが表示されます。
<各項目について上から見ていきます>
Open Methodは、USB / PCI / Bluetooth SSP / TCP Emulator Client & TCP Emulator Server
から選ぶことができます。今回はUSBにします。
基本的には、Auto Openにチェック入れて良いかと思います。
もし、任意のタイミングでOpen()したいのであれば、
private SerialPortUtility.SerialPortUtilityPro serialPort;
public void OpenFunc()
{
serialPort = this.GetComponent<SerialPortUtility.SerialPortUtilityPro>();
serialPort.OpenMethod = SerialPortUtility.SerialPortUtilityPro.OpenSystem.USB;
serialPort.VendorID = "";
serialPort.ProductID = "";
serialPort.SerialNumber = "";
serialPort.BaudRate = 9600;
//serialPort.ReadProtocol = SerialPortUtility.SerialPortUtilityPro.MethodSystem.Streaming; //受信の設定なので今回は省略
//serialPort.ReadCompleteEventObject.AddListener(this.ReadComprateString); //read function //受信の設定なので今回は省略
//serialPort.RecvDiscardNull = true; //受信の設定なので今回は省略
serialPort.Open();
}
のように書いて、ボタントリガーなどで呼び出します。
次に、**[Show the devices connected to this PC.]**ボタンをクリックすると、
今パソコンに接続されているUSBデバイスのどれを選択しますか?みたいなのがでてきます。
選択すれば自動的に
Vender ID
Product ID
Serial Number ※空欄になるデバイスもあります(その場合空欄でOK)
Order
に番号を入れてくれます。
基本的には以下のような設定がデフォルトです。
BaundRate・・・9600bps
Parity・・・No
Stop Bit・・・One Bit
Data Bit・・・Eight Bit
Discard Null Receive・・・一般的にどっちかわかんないです
Auto RTS/CTS Handshake・・・はずす
Start DTR Enable・・・いれる
※各用語について分からないなりに調べてみました。
BaundRate(ボーレート)・・・通信速度。単位はbps(bit Per Second)で、300、600、1200、2400、4800、9600、19200などから選択します。
RTS・・・相手側(シリアルデバイス)が正常に動作しているか(電源が入っているか)
DTR・・・こちら側(パソコン)が正常に動作しているか(電源が入っているか)
CTS・・・こちらから相手にデータを送る要求
DSR・・・相手からこちらにデータを送る要求
ハンドシェイク・・・フロー制御のこと。互いに今送受信の状況を確認しあう事で通信の信頼性を確保?するらしい…(よくわからなかった)
##シリアル通信(送信)のメソッドをつくる
SerialPortUtilityProとは別に、
新しいC#ファイルを用意します。
シーン上の好きなオブジェクトにアタッチしておきます。
今回私は、ONボタントリガーでRelayOn()呼び出し、OFFボタントリガーでRelayOff()が呼び出されるコードをつくりました。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class SerialHandler : MonoBehaviour
{
SerialPortUtility.SerialPortUtilityPro serialPort;
private string _on = "relay on 0";
private string _off = "relay off 0";
void Awake()
{
serialPort = this.GetComponent<SerialPortUtility.SerialPortUtilityPro>();
}
public void RelayOn()
{
if (serialPort != null)
{
if (serialPort.IsOpened())
{
serialPort.WriteCR(_on);
}
}
}
public void RelayOff()
{
if (serialPort != null)
{
if (serialPort.IsOpened())
{
serialPort.WriteCR(_off);
}
}
}
}
serialPort = this.GetComponent<SerialPortUtility.SerialPortUtilityPro>();
で、
serialPortをUnityアプリ起動時に取ってくる必要があります。
SerialPortUtilityPro.csがアタッチされているオブジェクトから参照するようにします。
(同じオブジェクトにアタッチしているので、thisにしています)
また、Write()
についても何種類かあるので注意です。
Write("Hello!")・・・Write(“Hello!”);
WriteCRLF("Hello!")・・・Write(“Hello!\r\n”); と等価
WriteCR("Hello!")・・・Write(“Hello!\r”); と等価
WriteLF("Hello!")・・・Write(“Hello!\n”); と等価
先頭にもどるか?改行するか?を正しく指定しないと、シリアルデバイスが動きません。
もし、あれ?動かない ということがあったら、ここを見直すと良いかもしれません。
(私の場合はWriteCRが正しく動作しました。)
##まとめ
Serial Port Utility Proはとっても簡単。