質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

シリアルポート

シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

1回答

9753閲覧

Unity COMポートへ送信(シリアル通信・System.IO.Ports)

aaachi

総合スコア69

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

シリアルポート

シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2019/07/05 10:52

編集2019/07/08 10:48

いつもお世話になっております。

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)」と認識されています。)
それも原因だったりするのかな、と考えています。

リレー基盤 https://www.elefine.jp/SHOP/USBPOWERRELAY1.html

ヒントを教えて頂けないでしょうか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}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

コードを見る限り異常は見当たりませんが、VisualStudioなどのデバッグ機能を持つ環境で走らせて、
Start関数は実行されているか、serialPort_変数がどの段階でnullになるかモニタしてみればどうでしょう

投稿2019/07/05 13:13

編集2019/07/08 01:52
y_waiwai

総合スコア87749

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

aaachi

2019/07/08 01:00

回答頂きありがとうございます! setup関数というのは、どのコードにあたりますでしょうか。 宜しくお願い致します。
y_waiwai

2019/07/08 01:50

ああ、Setupじゃなく、Start関数です そこでserialPortがnewされるので、その関数を実行したあと、nullでないのを確認しておきます
y_waiwai

2019/07/08 01:52

ややこしいので回答を修正しておきます
aaachi

2019/07/08 03:29

お返事頂きありがとうございます! 確認してみたところ、 newされる行でエラーがでており、生成できていないためにnullになっていることがわかりました。 エラー内容について、追記修正しました ご確認頂けますと幸いです。 宜しくお願い致します。
y_waiwai

2019/07/08 03:38

ソースをバックアップしといて、最初からプロジェクトを作り直してみてはどうでしょう
ozwk

2019/07/08 03:47

ユニバーサルwindowsプラットフォーム(UWP)は (その文脈だと)windowsとまた違うんですよ。
aaachi

2019/07/08 04:29

@y_waiwai様 新しくプロジェクトを作り直してみたところ、上記エラーがとれました! エラーはでないものの、プレビュー開始&プレビュー抜けると、unityが応答しなくなってしまう状況になっています。 もうすこし調べてみて、再度質問させて頂ければと思います。
aaachi

2019/07/08 04:31

@ozwk様 回答頂きありがとうございます! そうなのですね。ビルドしてみたのですが、winアプリケーション みたいなかんじでしょうか。 とりあえず、プロジェクトを作り直してからUWPにしてみたろころ、 エラーが消えましたので、このままwinアプリとして生成するとこまで頑張ってみようと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問