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

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

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

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

Arduino

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

Q&A

解決済

2回答

2265閲覧

Unity(送信側)とArduino(受信側)のシリアル通信

xyzm

総合スコア1

Unity

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

Arduino

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

0グッド

0クリップ

投稿2021/06/11 04:13

編集2021/06/11 06:12

前提・実現したいこと

Unityから座標のデータをarduino側へ送り、Unity側のキューブが特定の範囲内に入ったらLEDを光らせることをしたい。

発生している問題・エラーメッセージ

Unity側もarduino側にもエラーが出ていないのにも関わらず、シリアル通信ができていない。

エラーメッセージ なし。 ### 該当のソースコード Unity側1つ目 オブジェクトの座標を表示 using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class NewBehaviourScript : MonoBehaviour { // Start is called before the first frame update public Text positiontext; void Start() { } void OnMouseDrag() { Vector3 objectPointInScreen = Camera.main.WorldToScreenPoint(this.transform.position);  Vector3 mousePointInScreen = new Vector3(Input.mousePosition.x, Input.mousePosition.y, objectPointInScreen.z); Vector3 mousePointInWorld = Camera.main.ScreenToWorldPoint(mousePointInScreen); mousePointInWorld.z = this.transform.position.z; this.transform.position = mousePointInWorld; positiontext.text = "x:" + this.transform.position.x.ToString() + "y:" + this.transform.position.y.ToString() ; } } Unity側 2つ目 Unity側からarduino側にデータを送るプログラム using System.IO.Ports; using UnityEngine; using System.Collections; using System.Collections.Generic; public class Serialconnect : MonoBehaviour { private SerialPort serial; private void Awake() { serial = new SerialPort("COM1", 9600); serial.Open(); } private void Update() { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);//光線をマウスで提示 RaycastHit hit = new RaycastHit();// if (Physics.Raycast(ray, out hit))//オブジェクトの接触判定 { Vector2 pos = this.transform.position; float x = pos.x; float y = pos.y; string str; string str1; string str2; str1 = x.ToString(); //float型から文字列の変換 str2 = y.ToString();//float型から文字列の変換 str = str1 + ',' + str2 + ';'; serial.Write(str); Debug.Log(str); Debug.Log(str1); Debug.Log(str2); } } } Arduino側 String cmds[2];// 分割された文字列を格納する配列 float X = 0.0; //受信したデータはここに格納される。 float Y = 0.0; float Z = 0.0; void setup(){ Serial.begin(9600); pinMode(12,OUTPUT); pinMode(13,OUTPUT); } int split(String data, char delimiter, String*dst){ int index = 0; int arraySize = (sizeof(data)/sizeof((data)[0])); int datalength = data.length(); for (int i = 0; i < datalength; i++) { char tmp = data.charAt(i); if ( tmp == delimiter ) { index++; if ( index > (arraySize - 1)) return -1; } else dst[index] += float(tmp); } return (index + 1); } void loop(){ //データを1つ受信する関数(割り込み処理)です。 String myString = Serial.readStringUntil(';'); int index = split(myString,',',cmds); if(Serial.available() >= 2){ String str1=cmds[0]; String str2=cmds[1]; X=str1.toFloat(); Y=str2.toFloat(); if(X<0.0 && Y<0.0){ digitalWrite(12,LOW); } else if(X>0.0 && Y<0.0){ digitalWrite(13,LOW); } } delay(50); } ### 試したこと 別件だがUnity側で特定のキーを押したらLEDが光るプログラムを使いシリアル通信自体は成功させています。 だれかわかる方いらっしゃいましたら是非おしえていただきたいです。 追記 arduino側についてるLEDがずっと光ったままなのでarduino側が原因かもしれないです。

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

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

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

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

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

guest

回答2

0

ベストアンサー

Arduino

1int split(String data, char delimiter, String*dst){ 2 int index = 0; 3 int arraySize = (sizeof(data)/sizeof((data)[0]));

arraySizedataの長さを表していません。

例えば
ESP32でString s = "01234567890123456789";、と"1"の両方の場合において、
sizeof(s)/sizeof(s[0])を表示すると12になります。

(dataSizeを使えばよいのでは?)


参考元のコードからして結構無茶苦茶でしたが
arraySizeを使って何がしたかったのか意図を推測するに、
dstの要素以上に元文字列を分割したら-1を返す」
という仕様なのでしょう。

そもそもこの仕様が妥当なのかはさておき、
ということは引数にdstの要素数も追加しなければいけません。


さて、仮にsplit()が問題なく動いたとしましょう

Arduino

1String myString = Serial.readStringUntil(';'); 2int index = split(myString,',',cmds); 3if(Serial.available() >= 2){ // このif文の条件はなに?

「カンマ区切りで要素2つを受信したら以下の処理を行いたい」はずですから
条件分が全然合ってませんね、
Serial.available() >= 2は「シリアルに受信しているけど取り出していない文字が2つ以上」の意ですから。

投稿2021/06/11 04:22

編集2021/06/11 05:48
ozwk

総合スコア13521

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

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

xyzm

2021/06/11 05:32

ご回答ありがとうございます!そのサイトを参考にしました。今の回答から察するとint arraysize=datasize(data)にすれば良いということでしょうか?
ozwk

2021/06/11 05:38

いや、よく読んだらそこは的外れでした。
xyzm

2021/06/11 06:48 編集

そうですね。よくよく見たら、readがavailableの後ろにないと条件が成り立たないですね。ありがとうございます。
guest

0

まずは、きちんと送信できているかを確認しましょう
もう一台PCを用意し、Teratermなどで、シリアル通信できるようにしておきます
それをつないで、想定した送信のメッセージが出ているのかを確認しましょう

きちんと送信のメッセージが確認できるなら、問題はArduino側です。
確認できないなら、Unity側の問題となります

投稿2021/06/11 04:25

y_waiwai

総合スコア87774

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

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

xyzm

2021/06/11 06:33

Unity側を実際に動かしてやってみたところ、arduino側でLEDがずっと光っていましたので問題はarduino側だと思っています。arduino側が原因だと思っています。ですがLEDがなぜずっと光っているのかが理解できません。arduino側のプログラムでおかしいところがあれば教えていただきたいです。
y_waiwai

2021/06/11 06:40

loop関数のなかで、 digitalWrite(12,LOW); と、LOWにするところはあっても、HIGHにするところがないですね 回路図が提示されてないのでわかりませんが、LOWで点灯するなら、消灯しないのは当たり前ってはなしになりますね
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問