NP-Complete
NP-Complete

Reputation: 61

Serial Communication Running Slow in Unity

I have connected IMU (Gyroscope&Acc&Magnetometer) to my Unity3D project and using serial communication via USB.

The problem is, when my script becomes little heavy with gaming codes, serial communication slows down - when values from IMU are supposed to change at certain point of time, they change after couple of seconds and as time goes, data stream cannot catch up with the game.

I am calling myPort.ReadLine() from Update function to read serial data from COM port.

What is the solution? - If I understand the problem right, I want the serial data reading not to be waiting to my app's next frame to receive new values.

May reducing Baud Rate of the IMU device work?

Upvotes: 3

Views: 3224

Answers (2)

NP-Complete
NP-Complete

Reputation: 61

So I figured the best solution for the problem - threading.

Since serial data has it's own speed and must not be depended on the game update frequency (otherwise it causes the serial stream to buffer and huge lagging accures), the following solution worked for me:

In the initialization function (init) I call invokeRepeating - timer that repeats itself every 0.01 seconds and in that timer, I call a thread for reading serial data.

Here is the pseudocode of the timer function:

 void timerfunction ()
 {
   if (! threadAlive){
     Start new thread - SerialThread ()
     threadAlive = true;
   }
}

void SerialThread ()
{
  Read the Serial Data..
  threadAlive = false:
}

This way, when there is a problem inside serial port, game won't lag because the thread takes the pressure on itself.

InvokeRepeating will make sure the threading (reading data) is attempted to be called every fixed (desirable) amount of time and therefore serial data will not buffer.

Worked just fine for me. Serial data speed was about 16Hz and gameplay framerate was - 10-100 fps.

Upvotes: 0

aubatmaz
aubatmaz

Reputation: 133

There are several things you can do for optimizing your project:

1) You can change the communication parameters. If you are sending pitch, yaw or roll, don't send them as string, instead use IEEE 754 format, send them as bytes. Also, if you are getting Quaternion values, do not loose time to convert them to Euler Angles.

2) Try to change your update rate in Unity from settings but be careful smaller update rate = slower unity frame rate.

3) Try to use high baud rate, such as 115200 or higher. If you reduce baud rate, your data from IMU can be corrupted.

4) In IMU code, you can toggle you serial port communication (you may not want to send all data continuously, you may send data shirkingly). I mean, you can downsample your data.

5) I don't know your data size but you can use Coroutines & Yield or Invoke. As you know, Unity does not allow us to use data received event but you can create your own event to understand if all of your data has been received. (Also try discardInBuffer if you have problem with streaming)

6) You can write your own dll (c# dll does not make any bigger changes by the way so use C++). If you are using Windows, you can start searching with kernel32.Dll and ws2_32.dll.

Upvotes: 3

Related Questions