Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by refsus · May 10, 2013 at 07:58 AM · delayarduinodrawcall

High drawcall make delay when read variable from serial port

I have game that connected with arduino, my game have 500 drawcalls, when I try read variable from serial port, there's delay about 1-5 sec. But when the drwacalls less than 300 there's no delay when read the serial port. Is that the large amount of drawcalls make delay when read variable from serial port? Here's my code :

 using UnityEngine;
 using System.Collections;
 using System.IO;
 using System.IO.Ports;
 using System.Threading;
 
 public class Micro : MonoBehaviour
 {
     string strIn;
     string FileName;
     StreamReader reader;
     string COM;
     int EnableMicro;
     public static int a1 = 0;
     public static int a2 = 0;
     public static int d1 = 0;
     public static int d2 = 0;
     public static int d3 = 0;
 
     SerialPort serial;
     private string[] data;
 
     string[] fungsi;
     string[] nilai;
     float TimerMicro;
     string value;
 
     void Start()
     {
         LoadConfig();
         if (EnableMicro == 1)
         {
             serial = new SerialPort(COM, 9600, Parity.None, 8, StopBits.One);
             //serial.Open();
             OpenConnection();
         }
         //serial.ReadTimeout = 1;
     }
 
     void Update()
     {
 
         //Debug.Log(value);
         if (EnableMicro == 1)
         {
             //TimerMicro += Time.deltaTime;
             try
             {
                 value = serial.ReadLine();
             }
             //if (TimerMicro > 1.0f)
             //{
             catch
             {
                 value = ("a1=0 a2=0 d1=0 d2=0");
             }
             if (value != null)
             {
                 fungsi = value.Split('=');
                 try
                 {
                     nilai = fungsi[1].Split(' ');
                     a1 = int.Parse(nilai[0]);
                 }
                 catch
                 {
                     a1 = 0;
                 }
 
                 //fungsi = value.Split('=');
                 try
                 {
                     nilai = fungsi[2].Split(' ');
                     a2 = int.Parse(nilai[0]);
                 }
                 catch
                 {
                     a2 = 0;
                 }
 
                 //fungsi = value.Split('=');
                 try
                 {
                     nilai = fungsi[3].Split(' ');
                     d1 = int.Parse(nilai[0]);
                 }
                 catch
                 {
                     d1 = 0;
                 }
 
                 //fungsi = value.Split('=');
                 try
                 {
                     nilai = fungsi[4].Split(' ');
                     d2 = int.Parse(nilai[0]);
                 }
                 catch
                 {
                     d2 = 0;
                 }
             }
             //Debug.Log(value);
             //Debug.Log("Fungsi 1:" + fungsi[0] + " Fungsi2:" + fungsi[1] + " Fungsi3:" + fungsi[2] + " Fungsi4:" + fungsi[3]);
 
             //fungsi = value.Split('=');
             //nilai = fungsi[5].Split(' ');
             //d3 = int.Parse(nilai[0]);
             //Debug.Log("L=" + L + " R=" + R + " U=" + U + " D=" + D + " RUN=" + RUN);
             Debug.Log("a1=" + a1 + "   a2=" + a2 + "   d1=" + d1 + "   d2=" + d2);
             ////if (L == 1)
             ////    Debug.Log("Kiri");
 
             ////if (R == 1)
             ////    Debug.Log("Kanan");
 
             ////if (U == 1)
             ////    Debug.Log("Atas");
 
             ////if (D == 1)
             ////    Debug.Log("Bawah");
 
             //strIn=("L="+L+" R="+R+" U="+U+" D="+D+" RUN="+RUN);
             //Debug.Log(strIn);
             //return strIn;
             //}
         }
     }
 
     void OnGUI()
     {
         GUI.Label(new Rect(Screen.width - 100, (Screen.height) - 20, 120, 30), "a1: " + a1);
         GUI.Label(new Rect(Screen.width - 200, (Screen.height) - 20, 120, 30), "a2: " + a2);
         GUI.Label(new Rect(Screen.width - 300, (Screen.height) - 20, 120, 30), "d1: " + d1);
         GUI.Label(new Rect(Screen.width - 400, (Screen.height) - 20, 120, 30), "d2: " + d2);
     }
 
     public void LoadConfig()
     {
         FileName = "Config.txt";
         if (!File.Exists(FileName))
         {
             return;
         }
         else
         {
             reader = File.OpenText(FileName);
             string buffer;
 
             buffer = reader.ReadLine();
             string[] token = buffer.Split(':');
             COM = (token[1]);
 
             buffer = reader.ReadLine();
             token = buffer.Split(':');
             EnableMicro = int.Parse(token[1]);
 
             reader.Close();
         }
     }
 
     void OpenConnection()
     {
         if (serial != null)
         {
             if (serial.IsOpen)
             {
                 serial.Close();
                 Debug.Log("Closing port, because it was already open!");
             }
             else
             {
                 try
                 {
                     serial.Open();  // opens the connection
                     serial.ReadTimeout = 10;  // sets the timeout value before reporting error
                     Debug.Log("Port Opened!");
                 }
                 catch
                 {
                     Debug.Log("com False");
                 }
             }
         }
         else
         {
             if (serial.IsOpen)
             {
                 // print("Port is already open");
                 Debug.Log("Port is already open");
             }
             else
             {
                 //print("Port == null");
                 Debug.Log("Port == null");
             }
         }
     }
     void OnApplicationQuit()
     {
         if (serial != null)
             serial.Close();
     }
 }

and this the pictures :

alt text

Anyone can solve my problem? Thank you :)

serial.png (13.3 kB)
Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Fattie · May 10, 2013 at 07:59 AM 1
Share

Instant kudos for Arduino

1 Reply

· Add your reply
  • Sort: 
avatar image
2
Best Answer

Answer by Bunny83 · May 10, 2013 at 10:47 AM

You use a readtimeout of 10 ms, so each call to serial.ReadLine(); will block your whole game for 10ms (except when a line is available). You should handle hardware IO stuff in a seperate thread.

Something like that:

 //SerialPortLineReader.cs
 using System;
 using System.Collections.Generic;
 using System.Threading;
 using System.IO.Ports;
 
 public class SerialPortLineReader
 {
     private SerialPort m_SerialPort = null;
     private Thread m_ReadLoop = null;
     private object m_LockHandle = new object();
     private List<string> m_Lines = new List<string>();
 
     public bool IsDataAvailable
     {
         get
         {
             lock (m_LockHandle)
             {
                 return m_Lines.Count > 0;
             }
         }
     }
 
     public string ReadLine()
     {
         string tmp = null;
         lock (m_LockHandle)
         {
             if (m_Lines.Count > 0)
             {
                 tmp = m_Lines[0];
                 m_Lines.RemoveAt(0);
             }            
         }
         return tmp;
     }
 
 
     public SerialPortLineReader(SerialPort aSerialPort)
     {
         m_SerialPort = aSerialPort;
         m_ReadLoop = new Thread(_ThreadFunc);
         m_ReadLoop.IsBackground = true;
         m_ReadLoop.Start();
     }
 
     private void _ThreadFunc()
     {
         while (m_ReadLoop.ThreadState != ThreadState.StopRequested)
         {
             string tmp = m_SerialPort.ReadLine();
             lock (m_LockHandle)
             {
                 m_Lines.Add(tmp);
             }
         }
     }
 }

Use this class like that:

 SerialPort port = new SerialPort( .... );
 SerialPortLineReader reader = new SerialPortLineReader( port );
 // ...
 
 string line = reader.ReadLine();
 if (line != null)
 {
     //...

This will seperate the io reading from your gameloop and only sync when you want to access data.

Btw: I just thrown this class together without testing it, but it should work ;)

Comment
Add comment · Show 5 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Bunny83 · May 10, 2013 at 10:50 AM 0
Share

Note: the class lacks of proper port closing. Usually the OS will close any open ports of a program when it ends. However closing the port manually could cause an exception in the background thread. You might want to implement some checks for that ;)

Btw: in your OpenConnection function the else block of if (serial != null) will cause a null-ref-exception when serial is really null since you check serial.IsOpen on a known null reference.

avatar image Fattie · May 10, 2013 at 11:30 AM 0
Share

Awesomeness

avatar image refsus · May 13, 2013 at 08:23 AM 0
Share

thank for your answer Bunny83, I will try later, but now I got fever :(

avatar image Fattie · May 13, 2013 at 08:40 AM 0
Share

You have a FEVER ? $$anonymous$$y God, that's horrible. Eat more meat. If you can read German I strongly recommend Leben ohne Brot, Dr. Wolfgang Lutz ISBN:3887601009

avatar image rightdroid · Feb 26, 2019 at 09:47 AM 0
Share

Thank you, this saved me some serious headache.

I had a relatively old PC reading serial port and changing images according to the received data, but the serial data came in extremely slow/lagging behind. After delegating serial port reading to another thread, it seemed to fix that, but then introduced an ever-increasing lag between what sensor saw and what Unity read from serial port. What did the trick was to flush serial port buffer after reading it - port.DiscardOutBuffer() and port.DiscardInBuffer().

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

17 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Long delay sending data to Arduino via Serial Communication 0 Answers

Why do await Task.Delay(10); stops execution in unity Web-GL? 1 Answer

How to read two separate values from the same SerialPort? 1 Answer

How do i Smooth ingame movement with flickering sensor input? 0 Answers

Map some Values taken from Serial Port 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges