- Home /
Slow reading from Unity via Arduino!! URGENT!
Hi guys, I need some help speeding up the readings in Unity 3D. Thus far I am able to read X and Y values in the Arduino through COM8. The problem occurs when I try and read both values in Unity. It reads fast (when I look at the serial monitor in the arduino IDE) but when I press play in Unity there is a tremendous lag between the time the X and Y values change and the time Unity displays/reads those values.
THE ARDUINO CODE(the necessary part):
int values[] = {round(X),round(Y)};
Serial.flush();
Serial.print(values[0]);
Serial.print(",");
Serial.print(values[1]);
Serial.println();
delay(10);
and THE UNITY CODE:
using UnityEngine; using System.Collections; using System.IO.Ports;
public class RightWheel : MonoBehaviour {
public float speed;
public float MoveBy;
public int X = 0;
public int Y = 0;
SerialPort sp = new SerialPort("COM8", 9600);
// Use this for initialization
void Start () {
sp.Open();
sp.ReadTimeout = 1;
}
// Update is called once per frame
void Update () {
string value = sp.ReadLine(); //Read the information
string[] vec3 = value.Split(',');
X = int.Parse(vec3[0]);
Y = int.Parse(vec3[1]);
}
}
Are you getting any Timeout exceptions thrown? Also, have you considered trying to read this serial port asynchronously? There might be some thread issues.
YES,you are right! I have a Timeout exception, it's as follows (as I am unaware what it means):
TimeoutException: The operation has timed-out. System.IO.Ports.WinSerialStream.Read (System.Byte[] buffer, Int32 offset, Int32 count) System.IO.Ports.SerialPort.read_byte () System.IO.Ports.SerialPort.ReadTo (System.String value) System.IO.Ports.SerialPort.ReadLine () (wrapper remoting-invoke-with-check) System.IO.Ports.SerialPort:ReadLine () RightWheel.Update () (at Assets/RightWheel.cs:26)
As for reading it asynchronously, I am unaware of that technique. Thank you for that heads up though, as I've been trying to find different methods of sending multiple values through the serial port. I will look it up, but it would be nice if you had any advice?
To debug this, you might want to change your ReadTimeout property to something a bit longer; right now you are ti$$anonymous$$g out if no line is read within 1 millisecond.
I asked about the async possibility because reading from the serial port with ReadLine() will block the main thread, and I believe Unity scripts run in the GUI thread. If this is so, then that might explain some of the lag. Have you checked out the $$anonymous$$SDN documentation on SerialPort? The examples there read the port on a separate thread. Files, ports, etc. are often read/written asynchronously because of this issue, so this would be a good technique to look into.
Answer by Ubahs · Apr 03, 2013 at 05:29 AM
Alongside what mhtraylor said, your Arduino code is delaying for 10 ms and your Unity code is only waiting for 1 ms. That means your Unity code will timeout 10 times for every time it actually gets data (since you're using SerialPort.ReadLine() you'll get a TimeoutException).
If you increase the timeout in Unity to higher, you'll probably end up freezing Unity until the Arduino sends data, which a bad idea. Especially since 10ms is an eternity to a computer. But, if you're not too worried, just changing
sp.ReadTimeout = 1;
to
sp.ReadTimeout = 100;
should help you get further.
Alternatively, you could wrap your ReadLine() in a try/catch:
// Update is called once per frame
void Update () {
try
{
string value = sp.ReadLine(); //Read the information
string[] vec3 = value.Split(',');
X = int.Parse(vec3[0]);
Y = int.Parse(vec3[1]);
}
catch(TimeoutException) {}
do something async (like mhtraylor suggests), Unity Coroutines might be helpful, pass the data between threads, or just use the SerialPort DataReceived event. Which will call a method every time your Arduino sends data. Example for that event is at: Serial Port DataReceivedEvent
Good luck!
I'm in the middle of solving this lag issue as well. I would LOVE to use SerialPort DataReceived event but i cannot get it to work for the life of me. Do you have any further info on it?
$$anonymous$$ono does not support SerialPort Events. I'm also trying to work around this.
me too. I could not get SerialPort DataReceived event to work. By the way, I noticed that I have to set myPort.NewLine = "\n" (it's default value is actually "\r\n" which prevent ReadLine() method to work and lead to TimeoutException).
Answer by alexLMAD · Apr 21, 2015 at 01:14 PM
try with this in unity, work for me
if ((cadena=sp.ReadLine()) != null)
{
data = cadena.Split(',');
variable= int.Parse(data[0]);
volante = int.Parse(data[1]);
freno = int.Parse(data[2]);
clutch = int.Parse(data[3]);
}
Answer by Chevy-Monster · Jan 23, 2016 at 12:23 AM
This is my code for getting six (6) on or off switches from my arduino into unity. The arduino code is sending thestate of 7 switches, sequentially and continuously. Button 9 is a placeholder at the start of the data string, so if SetSwitches() reads anything else first, it's not the beginning of the string of inputs.
void Update ()
{
if (WalkPort.IsOpen) {
try {
Button9 = WalkPort.ReadByte ();
Button2 = WalkPort.ReadByte ();
Button3 = WalkPort.ReadByte ();
Button4 = WalkPort.ReadByte ();
Button5 = WalkPort.ReadByte ();
Button6 = WalkPort.ReadByte ();
Button7 = WalkPort.ReadByte ();
SetSwitches ();
} // <<< -------------------------------- END OF TRY
catch (System.Exception) {
throw;
} // <<< ------------------------------- END OF CATCH
} // <<< ------------- END OF WalkPort.IsOpen
} // <<< --- END OF UPDATE
Your answer
Follow this Question
Related Questions
how can i see serial port speed 1 Answer
New Problem 1 Answer
Is there any way to call CUDAfy.net into Unity? 1 Answer
Using Unity Free Licence in my company 1 Answer
Is there a better way to send data from Arduino to Unity? 0 Answers