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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

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

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

Q&A

1回答

5821閲覧

Unityの再生ボタンを押すとシリアル通信が止まってしまう

daaaisuke

総合スコア34

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

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

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

0グッド

1クリップ

投稿2016/09/26 14:28

編集2022/01/12 10:55

###前提・実現したいこと
Arduinoのセンサの値をUnityに送ってセンサの値をビジュアライズしたいと考えています。
シリアルポートを使用しているのですが、その最中にどうしてもわからないことがありました。

###発生している問題・エラーメッセージ
問題:Unityを再生すると、シリアルポートで値を受け取れなくなる

###問題のコード
Unity側

C#

1using UnityEngine;//unityのデフォルトの機能を使うためのクラス 2using System.Collections;//C#のデフォルト機能を使うためのクラス 3using System.IO.Ports;//シリアル通信を使用するためのクラス 4using System.Threading;//スレッド機能を利用可能にするためのクラス 5 6public class SerialHandler : MonoBehaviour 7{ 8 public delegate void SerialDataReceivedEventHandler(string message);//SerialDataReceivedEventHandlerというデリゲート(関数を入れる変数)の宣言 9 public event SerialDataReceivedEventHandler OnDataReceived;//OnDataReceivedという名前のデリゲートを生成 10 11 public string portName = "/dev/cu.usbmodem1411";//arduino側と同じシリアルポートを入れる 12 public int baudRate = 9600;//arduino側と同じボーレートを入れる 13 14 private SerialPort serialPort_;//serial portクラスのインスタンス生成 15 private Thread thread_;//スレッドクラスのインスタンス生成 16 17 private bool isRunning_ = false;//シリアルポートが開いているかどうか 18 private bool isNewMessageReceived_ = false;//シリアルポートから値が送られてきているかどうか 19 20 private byte message_b;//シリアル通信で送られてきたデータを格納する変数 21 private char message_c;//シリアル通信で送られてきたデータを格納する変数 22 private string text_="";//message_cを溜める場所 23 24 private Object lock_object_ = new Object();//? 25 26 27 void Awake()//このスクリプトのインスタンス生成後,つまり一番最初に実行される関数 28 { 29 Open(); 30 serialPort_.ReadTimeout = 1; 31 } 32 33 void Update() 34 { 35 if (isNewMessageReceived_) {//値が送られてきたら 36 OnDataReceived(text_); 37 isNewMessageReceived_ = false; 38 text_=""; 39 } 40 } 41 42 void OnDestroy()//ゲーム終了時に一度だけ呼び出される 43 { 44 Close(); 45 } 46 47 48 49 50 private void Open()//シリアルポートを開いて、新しいスレッドを開く 51 { 52 serialPort_ = new SerialPort(portName, baudRate, Parity.None, 8, StopBits.One);//シリアルポートインスタンス生成 53 serialPort_.Open();//シリアルポートを開く 54 55 isRunning_ = true;//開いた証としてtrueに変更 56 57 thread_ = new Thread(Read);//新しいスレッドを作成してread関数を実行させる 58 thread_.Start();//thread開始 59 } 60 61 private void Close() 62 { 63 isRunning_ = false;//シリアルポートを閉じた証としてfalseに変更 64 65 if (thread_ != null && thread_.IsAlive) {//threadが存在しているなら 66 thread_.Join();//元のスレッドの統合 67 } 68 69 if (serialPort_ != null && serialPort_.IsOpen) {//シリアルポートにインスタンスが格納されていて、シリアルポートが開いていれば 70 serialPort_.Close();//シリアルポートを閉じる 71 serialPort_.Dispose();//バッファの解放とか? 72 } 73 } 74 75 private void Read() 76 { 77 while (isRunning_ && serialPort_ != null && serialPort_.IsOpen) {//シリアルポートが開いているかつシリアルポートインスタンスが存在する 78 System.Threading.Thread.Sleep(100); 79 Debug.LogFormat("bytes to read:{0}", serialPort_.BytesToRead); 80 if (serialPort_.BytesToRead > 0) {//受信したデータがあったら 81 lock (lock_object_) { 82 Debug.Log("成功!!"); 83 message_b = (byte)serialPort_.ReadByte();//一文字ずつデータを読み込む 84 message_c = (char)message_b; 85 text_ = text_ + message_c.ToString(); 86 Debug.Log("message_b="+message_b); 87 Debug.Log("message_c="+message_c); 88 Debug.Log("text_="+text_); 89 if(message_b==10){ 90 isNewMessageReceived_ = true;//メッセージを受け取った証として変更 91 } 92 } 93 } 94 } 95 } 96 97 public void Write(string message) 98 { 99 serialPort_.Write(message);//メッセージをシリアルポートで送る 100 } 101}

C++

1#include "CurieIMU.h"//Genuino101の加速度センサを使用するためのライブラリをインクルード 2 3namespace { 4const int AVERAGE_NUM = 10;//値をある程度均一化するための数字 5const int adjustX = 5;//センサの値を調整するための定数、水平面に置いた時のズレの値 6const int adjustY = -2; 7const int adjustZ = -1; 8} 9 10void setup() 11{ 12 Serial.begin(9600);//シリアル通信スタート 13 while (!Serial) { 14 ; // wait for serial port to connect. Needed for native USB port only 15 } 16 // IMUセッティング---------------------------------------- 17 CurieIMU.begin();//加速度センサ起動 18 CurieIMU.setAccelerometerRange(2);//加速度センサのレンジ(測定範囲)の設定 19} 20 21void loop() 22{ 23 delay(16);//fps60程度に調整 24 readAccelerometer(); 25 setLed(); 26 27} 28 29 30//function---------------------------------------------- 31void readAccelerometer() 32{ 33 int axRaw = 0, ayRaw = 0, azRaw = 0; //加速度センサの値を受け取るための変数を用意 34 CurieIMU.readAccelerometer(axRaw, ayRaw, azRaw);//加速度センサの値を読み取り格納 35 int x = 0, y = 0, z = 0;//加速度センサの値を均した値を格納する変数を用意 36 //値の平均化================================ 37 for (int i = 0; i < AVERAGE_NUM; ++i) {//AVERAGE_NUMで指定した数だけ加速度を測定して平均化する 38 x += axRaw; 39 y += ayRaw; 40 z += azRaw; 41 } 42 x /= AVERAGE_NUM; 43 y /= AVERAGE_NUM; 44 z /= AVERAGE_NUM; 45 46 //========================================= 47 int angleX = map(axRaw, -16384, 16384, -90, 90); //センサで受け取った値を角度に変換 48 int angleY = map(ayRaw, -16384, 16384, -90, 90); 49 int angleZ = map(azRaw, -16384, 16384, -90, 90); 50 51 angleX += adjustX;//角度を手動で調整 52 angleY += adjustY; 53 angleZ += adjustZ; 54 55 Serial.print(angleX); 56 Serial.print("\t"); 57 Serial.print(angleY); 58 Serial.println(""); 59} 60 61void setLed() 62{ 63 if ( Serial.available() ) { 64 char mode = Serial.read(); 65 switch (mode) { 66 case '0' : digitalWrite(13, LOW); break; 67 case '1' : digitalWrite(13, HIGH); break; 68 } 69 } 70} 71

###試したこと
ターミナルのcatコマンドで、Arduino側から値が送られてきているのを確認しながらUnityを再生。
→ターミナル側で値が送られてこなくなった?シリアルポートが止まった?のを確認。

このことからarduinoからPCに値を送ることはできているが、ソフトウェア側に何らかの問題があり、再生と同時にシリアルポートが止まっているのではないかと考えた。

###補足情報
たまにデータが最初の数バイトのみ送られてくる現象を確認。
しかし、unity側でシリアルポートを開くタイミングとArduino側で値が送られてくるタイミングの兼ね合いによって起こるもので、問題の根本は同じものであるのではないかと考えています。

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

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

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

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

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

guest

回答1

0

シリアル通信というのは経験がないのでわからないのですが、
UnityのビルドターゲットがPCであればPlayerSettingのRun In Backgroundのチェックがオフになっているかもしれません。

投稿2016/09/30 05:17

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

daaaisuke

2016/09/30 09:19

回答していただきありがとうございます! Run In Background はUnityのwindowがアクティブでない時にも動作を継続させるものと認識しているのですが、合っていますでしょうか? ちなみにチェックを入れてもやはりシリアル通信が止まってしまいました。 やはりプログラムに問題があるのでしょうか…。
退会済みユーザー

退会済みユーザー

2016/09/30 10:12

関係なかったようですね、すみません。 C#のソースのRead()内をデバッガー追ってみるのが早そうです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問