Long lag in serial communication with Arduino

I’m trying to have unity read in some serial data from an arduino in the serial log. I’m sending potentiometer data from an arduino to unity, right now I just want to read it in the Debug log.

The code kinda works, the data is sending correctly. But there’s a solid 10 second delay from when I move the potentiometer, to when the data shows up in the Unity log. The serial window in arduino works, and I wrote some similar code in visual basic, and it works fine in the VS console window too, so the problem is in unity. It doesn’t seem to be missing readings either, it’s just a very long delay before the data shows up.

My code is below, anyone have any ideas?

Also, to clarify, the FPS seems to be fine, the game is still perfectly responsive to the standard first person controller script. It’s not slowing down the game, it just seems like the data is delayed by a few seconds.

//Unity Code:

using UnityEngine;
using System.Collections;
using System.Threading;
using System.IO.Ports;

public class serialcom : MonoBehaviour

{
public static SerialPort sp;
public static string x;
public static string[] data;
public static string lin;
public static string rot;
public int debugcount = 1;
	
// Use this for initialization
void Start () 
{
	//Debug.Log ("Code started");
	OpenConnection();
	//Debug.Log ("initialzed properly");
}

void Update() 
	{
		try{
		x = sp.ReadLine ();
		data = x.Split(' ');
		lin = data[0];
		rot = data[1];
		Debug.Log (lin + " " + rot);
		}
		catch{Debug.Log ("Please Work");}
	}

	
public void OpenConnection() 
{
	sp = new SerialPort("COM4", 9600, Parity.None, 8, StopBits.One);
	Debug.Log ("OpenConnection started");
    if (sp != null) 
    {
       if (sp.IsOpen) 
       {
         sp.Close();
         Debug.Log ("Closing port, because it was already open!");
       }
       else 
       {
         sp.Open();  // opens the connection
         sp.ReadTimeout = 100;  // sets the timeout value before reporting error
        Debug.Log("Port Opened!");
       }
    }
    else 
    {
       if (sp.IsOpen)
       {
         print("Port is already open");
       }
       else 
       {
         print("Port == null");
       }
    }
		Debug.Log ("Open Connection finished running");
	}
	
void OnApplicationQuit()
    {
        if (sp != null)
            sp.Close();
    }
}

// Ardiuno code:


int pot1 = A0;
int pot2 = A1;
int pot1volt; 
int pot2volt;


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly: 

pot1volt = analogRead(pot1);
pot2volt = analogRead(pot2);

  Serial.print(pot1volt);
  Serial.print(" ");
  Serial.print(pot2volt);
  Serial.println();
  
  delay(1);
  
}

Well I figured it out actually, figure I’ll leave it here in case any else needs a reference. I set up the times so that it can only get 1 reading per timeout cycle. So I upped the arduino delay to 20 ms, and the in unity i set up readtimeout = 25. That seemed to do the trick very nicely.

Arduino:

int pot1 = A0;
int pot2 = A1;
int pot1volt; 
int pot2volt;


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly: 

pot1volt = analogRead(pot2);
pot2volt = analogRead(pot1);

  Serial.print(pot1volt);
  Serial.print(" ");
  Serial.print(pot2volt);
  Serial.println();
  
  delay(20);
  
  
}

Unity:

using UnityEngine;
using System;
using System.Collections;
using System.Threading;
using System.IO.Ports;

public class serialcom : MonoBehaviour

{
public static SerialPort sp;
public Transform player;
public static string x;
public static string[] data;
public static string lin;
public static string rot;
public int debugcount = 1;
public float moveSpeed = 10f;
public float turnSpeed = 50f;
public int lincons;
public int rotcons;
	
// Use this for initialization
void Start () 
{
	//Debug.Log ("Code started");
	OpenConnection();
	//Debug.Log ("initialzed properly");
}

void Update() 
	{
		
		x = sp.ReadLine ();
		sp.ReadTimeout = 25;
		data = x.Split(' ');
		lin = data[0];
		rot = data[1];
		lincons = Convert.ToInt32(lin);
		lincons = lincons / 25;
		rotcons = Convert.ToInt32(rot);
		rotcons = -((rotcons / 50) - 10);
		player.Translate(Vector3.forward * lincons * moveSpeed * Time.deltaTime);
		player.Rotate(Vector3.up, rotcons * turnSpeed * Time.deltaTime);
	}

	
public void OpenConnection() 
{
	sp = new SerialPort("COM4", 9600, Parity.None, 8, StopBits.One);
	Debug.Log ("OpenConnection started");
    if (sp != null) 
    {
       if (sp.IsOpen) 
       {
         sp.Close();
         Debug.Log ("Closing port, because it was already open!");
       }
       else 
       {
         sp.Open();  // opens the connection
         // sets the timeout value before reporting error
        Debug.Log("Port Opened!");
       }
    }
    else 
    {
       if (sp.IsOpen)
       {
         print("Port is already open");
       }
       else 
       {
         print("Port == null");
       }
    }
		Debug.Log ("Open Connection finished running");
	}
	
void OnApplicationQuit()
    {
        if (sp != null)
            sp.Close();
    }
}

The better way to do this is not reduce the delay time on Arduino, but use delegate callback in unity code like this.

Thank you! Very useful!

Thank you so much. This work perfect!

Arduino:

unsigned long t = 0;
int interval = 100;

void loop(){

   if (millis() - t > interval) {
        t = millis();

   Serial.print(angle[0]); //from MPU6050
   Serial.print("/");
   Serial.println(angle[1]);
   }
}

Unity:

void Start () {
	SP.Open ();
	SP.ReadTimeout = 101;

}