Как отправить несколько переменных через поток в Unity?

На данный момент у меня есть это для arduino.ino:

Serial.println(Variable1);

который делает это в Unity:

string variable1 = stream.ReadLine();
float x = float.Parse(variable1);
transform.Rotate (0, -x/1000, 0);

Мой вопрос: Как мне отправить 3 переменные из Arduino в Unity, чтобы я мог сразу поместить каждое значение в функцию transform.Rotate?

Например, в псевдокоде:

Arduino.ino
send(Variable1, Variable2, Variable3);

Unity
transform.Rotate(Variable1,Variable2,Variable3);

Надеюсь, это имеет смысл. Спасибо.

, 👍1


1 ответ


Лучший ответ:

0

Что вам нужно сделать, так это определить схему/протокол связи. Похоже, вы используете последовательный UART через USB.

В вашем первом примере используется простая схема: просто ASCII-представление переменной, за которой следует новая строка. то есть:

float x = 123.45;
Serial.println(x);

это просто выводит

"123.45\n"

вы можете продолжить этот шаблон

float x, y, z,
... // предположим, что x, y и z содержат значения
Serial.print(x);
Serial.print(' ');
Serial.print(y);
Serial.print(' ');
Serial.println(z);

это выводит что-то вроде:

"123.43 23.34, 42.24\n"

тогда ваш принимающий код будет делать что-то вроде

string line = stream.ReadLine();
string[] parts = line.Split(' ', StringSplitOptions.RemoveEmptyEntries)
float x = float.Parse(parts[0]);    
float y = float.Parse(parts[1]);    
float z = float.Parse(parts[2]);    

но это очень неэффективно, так как arduino необходимо преобразовать число с плавающей запятой в строку ASCII, а затем передать ее через последовательный порт, где она будет прочитана на другой стороне, а затем снова преобразована в число с плавающей запятой. В этом нет необходимости, вы можете сделать это в двоичном формате, он не будет удобочитаемым для человека, но при этом будет использоваться гораздо меньше места для передачи.

float x, y, z; // предположим, что они действительны
Serial.write(&x, sizeof(float));
Serial.write(&y, sizeof(float));
Serial.write(&z, sizeof(float));
// NB здесь следует написать конец сообщения или что-то еще, чтобы обрамить данные

и с другой стороны

byte[] data = new byte[12];
stream.Read(data, 0, 12);

float x = BitConverter.ToSingle(data, 0);
float y = BitConverter.ToSingle(data, 4);
float z = BitConverter.ToSingle(data, 8);

Как правило, вам также понадобится какой-то способ обрамления данных, поэтому вы можете начать с простого заголовка сообщения, например:

struct head
{
  int length;
  int code;
};

и вы пишете это так:

head header; //assume this is valid
Serial.write(&header, sizeof(header));

затем вы можете написать сообщение.

Возможно, вы также захотите реализовать некоторую контрольную сумму, чтобы убедиться, что вы правильно получили данные.

Таким образом вы можете создать несколько структур сообщений, т. е.

struct vect3d
{
  head header;
  float x;
  float y;
  float z;
}

просто заполните и отправьте

vect3d v3;
v3.head.length = sizeof(vect3d); // можно было бы вычесть sizeof(head), чтобы читатель всегда мог прочитать первые 8 байт и оттуда прочитать остальную часть сообщения
v3.head.code = VECT3D; // предположим, что это где-то определено
v3.x = 123.5;
v3.y = 23.4;
v3.z = 42.24;

Serial.write(&v3, sizeof(v3));

С другой стороны, можно прочитать первые 8 байтов, затем прочитать остальную часть сообщения в зависимости от длины и проанализировать его на основе кода.

,