いつもお世話になっております。
UnityでC#のコードから、
シリアルデバイスへ文字列を送信したいのですが、
途中でつまづいてしまったため、質問させて頂きたいです。
##実現したいこと
Unity C#
⇓ ボタントリガーで、serialPort.Write("relay on 0");
を送信
COM6
⇓
(リレー基盤がONになり、電子錠が動作する)
##実装状況
まず、Unityを用いずに、Tera Term というツールを用いて、
WindowsからCOM6へ"relay on 0"を送信する・・・成功
⇓
Unityでシリアル通信を行う実装方法を調べる
https://tomosoft.jp/design/?p=7256
⇓
System.IO.Portsに関するエラーを排除
https://qiita.com/Fox_Kei/items/dbe10141e36f6a91ee83
⇓
System.IO.Portsは使用できるようになったが、
ボタントリガーを押すと、serialPortがNull のエラーがでてしまう
(ここでつまづいています)
C#
1using UnityEngine; 2using System.Collections; 3using System.IO.Ports; 4using System.Threading; 5 6public class SerialHandler : MonoBehaviour 7{ 8 public string portName = "COM6"; 9 public int baudRate = 9600; 10 11 private SerialPort serialPort_; 12 private Thread thread_; 13 private bool isRunning_ = false; 14 15 private string message_; 16 private bool isNewMessageReceived_ = false; 17 18 private string _on = "relay on 0"; 19 private string _off = "relay off 0"; 20 21 void Start() 22 { 23 Debug.LogWarning("Start"); 24 Open(); 25 } 26 27 void Update() 28 { 29 Debug.LogWarning("Serial-Update"); 30 if (isNewMessageReceived_) 31 { 32 OnDataReceived(message_); 33 } 34 } 35 void OnDestroy() 36 { 37 Debug.LogWarning("OnDestroy"); 38 Close(); 39 } 40 41 private void Open() 42 { 43 serialPort_ = new SerialPort(portName, baudRate, Parity.None, 8, StopBits.One); 44 serialPort_.Open(); 45 46 isRunning_ = true; 47 48 thread_ = new Thread(Read); 49 thread_.Start(); 50 } 51 52 private void Read() 53 { 54 Debug.LogWarning("Read1"); // => 出力されていない 55 while (isRunning_ && serialPort_ != null && serialPort_.IsOpen) 56 { 57 Debug.LogWarning("Read2"); // => 出力されていない 58 try 59 { 60 message_ = serialPort_.ReadLine(); 61// Debug.LogWarning(message_); 62 isNewMessageReceived_ = true; 63 } 64 catch (System.Exception e) 65 { 66 Debug.LogWarning(e.Message); 67 } 68 } 69 } 70 71 private void Close() 72 { 73 isRunning_ = false; 74 75 if (thread_ != null && thread_.IsAlive) 76 { 77 thread_.Join(); 78 } 79 80 if (serialPort_ != null && serialPort_.IsOpen) 81 { 82 serialPort_.Close(); 83 serialPort_.Dispose(); 84 } 85 } 86 87 void OnDataReceived(string message) 88 { 89 Debug.LogWarning("OnDataReceived1"); 90 var data = message.Split( 91 new string[] { "\t" }, System.StringSplitOptions.None); 92 if (data.Length < 2) return; 93 94 try 95 { 96 } 97 catch (System.Exception e) 98 { 99 Debug.LogWarning(e.Message); 100 } 101 } 102 103 public void RelayOnBtnPush() 104 { 105 Debug.Log("RelayOnBtnPush()"); 106 Debug.Log(_on); 107 Debug.Log("serialPort_ = " + serialPort_); // => serialPort_ = 108 109 serialPort_.Write(_on + "\n"); // => serialPort_がNUllエラー 110 } 111 112 public void RelayOffBtnPush() 113 { 114 Debug.Log("RelayOnBtnPush()"); 115 116 serialPort_.Write(_off + "\n"); 117 } 118 119}
色々問題を検索してみて、
よくある原因としては、
「unityのSystem.IO.PortsクラスのBytesToReadが正常に動かない」
ということが多く書かれていたのですが、
BytesToReadは使用していません。
また、よく使用される、Arduinoやラズパイではなく、
リレー基盤というものを使用しるので(デバイスマネージャー上では「USB シリアル デバイス(COM6)」と認識されています。)
それも原因だったりするのかな、と考えています。
ヒントを教えて頂けないでしょうかm(__)m
ここまでの長文を読んでいただき、ありがとうございます。
##追記
どこでserialPrort_
がnullになっているのか確認してみたところ、
newされる行でエラー(下記)がでており、生成できていないためにnullになっていることがわかりました。
初めからあったエラーなのですが、
PlatformNotSupportedException: System.IO.Ports is currently only supported on Windows.
と出てしまいます。
「System.IO.Portsが現在はwindowsだけしかサポートされていません」、という意味と思いますので、
ビルドプラットフォームを、Universal Windows Platform に変更したのですが、
エラーが消えない状況です。
unity再起動も試みましたが、変わりませんでした。
PlatformNotSupportedException: System.IO.Ports is currently only supported on Windows.
System.IO.Ports.SerialPort..ctor (System.String portName, System.Int32 baudRate, System.IO.Ports.Parity parity, System.Int32 dataBits, System.IO.Ports.StopBits stopBits) (at <9eedbed1e64b4c2d97edd8d4a1e07964>:0)
(wrapper remoting-invoke-with-check) System.IO.Ports.SerialPort..ctor(string,int,System.IO.Ports.Parity,int,System.IO.Ports.StopBits)
SerialHandler.Open () (at Assets/Scripts/SerialHandler.cs:47)
SerialHandler.Start () (at Assets/Scripts/SerialHandler.cs:26)
お力貸して頂けますと幸いですm(__)m
##追記2
serialPort.ReadLine()
のコードで
The operation has timed-out
というエラーが出てしまいます。
今回、Unityから信号を送信するだけで受信は必要ないため、
ReadLine()
のコードをコメントアウトしてみたところ、
エラーははかなくなったのですが、
serialPort.Write()
を実行しても、COM6へ送信されていないような感じでした(電子錠が動作しない)
また、もうひとつ試みたこととして、
Windows10 & Unity5.x が 丁度シリアル通信のバグがある、
というような情報をいくつかみかけたため、Unity4.6もインストールしてみました。
ですが、状況は変わりませんでした。
https://twitter.com/kohack_v/status/855849304099041281
どのようにすると、UnityからCOMポートへ送信できますでしょうか?
引き続き、アドバイス頂けますと幸いです。
何卒宜しくお願い致します。
▽少し変更しました。(serialPort.ReadTimeout
を追加等しています。)
C#
1using UnityEngine; 2using System.Collections; 3using System.IO.Ports; 4using System.Threading; 5 6public class SerialHandler : MonoBehaviour 7{ 8 public delegate void SerialDataReceivedEventHandler(string message); 9 public event SerialDataReceivedEventHandler OnDataReceived = delegate { }; 10 11 public string portName = "COM6"; //各自のマイコンのCOMポート 12 public int baudRate = 9600; 13 14 private SerialPort serialPort_; 15 private Thread thread_; 16 private bool isRunning_ = false; 17 18 private string message_; 19 private bool isNewMessageReceived_ = false; 20 21 private string _on = "relay on 0"; 22 private string _off = "relay off 0"; 23 24 void Awake() 25 { 26 Open(); 27 } 28 29 void Update() 30 { 31 if (isNewMessageReceived_) 32 { 33 OnDataReceived(message_); 34 //Debug.Log(message_); //受信したデータの確認表示用 35 } 36 } 37 38 void OnDestroy() 39 { 40 Close(); 41 } 42 43 private void Open() 44 { 45 serialPort_ = new SerialPort(portName, baudRate, Parity.None, 8, StopBits.One); 46 serialPort_.ReadTimeout = 20; 47 serialPort_.Open(); 48 serialPort_.NewLine = "\n"; 49 50 isRunning_ = true; 51 52 thread_ = new Thread(Read); 53 thread_.Start(); 54 } 55 56 private void Close() 57 { 58 isRunning_ = false; 59 60 if (thread_ != null && thread_.IsAlive) 61 { 62 thread_.Join(); 63 } 64 65 if (serialPort_ != null && serialPort_.IsOpen) 66 { 67 serialPort_.Close(); 68 serialPort_.Dispose(); 69 } 70 } 71 72 private void Read() 73 { 74 while (isRunning_ && serialPort_ != null && serialPort_.IsOpen) 75 { 76 try 77 { 78 //message_ = serialPort_.ReadLine(); //ここでエラーがでる 79 isNewMessageReceived_ = true; 80 } 81 catch (System.Exception e) 82 { 83 Debug.LogWarning(e.Message); 84 } 85 } 86 } 87 88 public void Write(string message) 89 { 90 try 91 { 92 serialPort_.Write(message); 93 } 94 catch (System.Exception e) 95 { 96 Debug.LogWarning(e.Message); 97 } 98 } 99 100 public void RelayOnBtnPush() 101 { 102 Debug.LogWarning("RelayOnBtnPush()"); 103 104 try{ 105 Debug.Log("serialPort_ = " + serialPort_); 106 serialPort_.Write("relay on 0"); 107 } 108 catch (System.Exception e){ 109 Debug.Log(e.Message); 110 Debug.LogWarning("NO WRITE"); //エラーはでていないようです 111 } 112 finally { 113 Debug.LogWarning("FINISH WRITE"); 114 } 115 } 116 117 public void RelayOffBtnPush() 118 { 119 Debug.LogWarning("RelayOnBtnPush()"); 120 121 serialPort_.Write("relay off 0"); 122 } 123 124}

バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/07/08 01:00
2019/07/08 01:50
2019/07/08 01:52
2019/07/08 03:29
2019/07/08 03:38
2019/07/08 03:47
2019/07/08 04:29
2019/07/08 04:31