So I currently have this for arduino.ino:
Serial.println(Variable1);
that does this in Unity:
string variable1 = stream.ReadLine();
float x = float.Parse(variable1);
transform.Rotate (0, -x/1000, 0);
My question is; How would I send 3 variables from the Arduino to Unity so I can put each value into the transform.Rotate
function at once?
For example in pseudocode:
Arduino.ino
send(Variable1, Variable2, Variable3);
Unity
transform.Rotate(Variable1,Variable2,Variable3);
I hope this makes sense. Thank you.
1 Answer 1
What you need to do is define a communication scheme/protocol. You appear to be using the Serial UART via USB.
Your first example has a simple scheme its simply the ASCII representation of the variable followed by a newline. i.e. :
float x = 123.45;
Serial.println(x);
this simply outputs
"123.45\n"
you could continue this pattern
float x, y, z,
... // assume x, y and z have values in them
Serial.print(x);
Serial.print(' ');
Serial.print(y);
Serial.print(' ');
Serial.println(z);
this outputs something like:
"123.43 23.34, 42.24\n"
then your receiving code will do do something like
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]);
but this is very inefficient, since the arduino needs to convert the float to an ASCII string, then transmit that over the serial port, where its read on the other side, then parsed back into a float. One doesn't need to do this, you can do in binary, it won't be human readable, but it will use much less transmission space.
float x, y, z; // assume these are valid
Serial.write(&x, sizeof(float));
Serial.write(&y, sizeof(float));
Serial.write(&z, sizeof(float));
// n.b. one should write an end of message here or something else to frame the data
and on the other side
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);
You will generally also want some way to frame the data, so you might want to start with a simple message header, i.e.:
struct head
{
int length;
int code;
};
and you write it like:
head header; //assume this is valid
Serial.write(&header, sizeof(header));
then you can write you message.
You might also want to implement some sort of checksum, so you can verify that you got the data correctly.
You can create multiple message structures this way, i.e.
struct vect3d
{
head header;
float x;
float y;
float z;
}
just fill and send
vect3d v3;
v3.head.length = sizeof(vect3d); // one could subtract sizeof(head) off so the reader can always read the first 8 bytes and read the rest of the message from there
v3.head.code = VECT3D; // assume this is defined somewhere
v3.x = 123.5;
v3.y = 23.4;
v3.z = 42.24;
Serial.write(&v3, sizeof(v3));
On the other side one would read in the first 8 bytes, then read in the rest of the message based on the length, and parse it based on the code.