Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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
0
Question by davix10 · Nov 03, 2015 at 10:49 AM · unity 5serialport

Serial port on unity

Hi, I would like to use the serial port of unity but I can not make it work. First of all I do not understand why you can not find the serial port if I write

  sp = new SerialPort ( "COM58", 115200) ;

but I have to write

  sp = new SerialPort ( "\\\\.\\COM58", 115200) ;

Then, I wanted to use the event DataReceived but I can not make it work, every time gives me an error nullReferenceObject. I used the same method of visual studio without any problems. My question is: can you use the serial port of unity? If so, does anyone have any examples?

So, the serial port of instrument (not Arduino), I can not make work. I loaded settings .net 2.0 but keeps telling me that the COM port does not exist. This way I can not go on in my game. I downloaded a script that I found online:

 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 
 using System.IO.Ports;
 
 // System.IO.Ports requires a working Serial Port. On Mac, you will need to purcase the Uniduino plug-in on the Unity Store
 // This adds a folder + a file into your local folder at ~/lib/libMonoPosixHelper.dylib
 // This file will activate your serial port for C# / .NET
 // The functions are the same as the standard C# SerialPort library
 // cf. http://msdn.microsoft.com/en-us/library/system.io.ports.serialport(v=vs.110).aspx
 
 
 public class Serial : MonoBehaviour
 {
 
     /// <summary>
     /// Enable notification of data as it arrives
     /// Sends OnSerialData(string data) message
     /// </summary>
     public bool NotifyData = false;
 
     /// <summary>
     /// Enable line detection and notification on received data.
     /// Message OnSerialLine(string line) is sent for every received line
     /// </summary>
     public bool NotifyLines = false;
 
     /// <summary>
     /// Maximum number of lines to remember. Get them with GetLines() or GetLastLine()
     /// </summary>
     public int RememberLines = 0;
 
     /// <summary>
     /// Enable lines detection, values separation and notification.
     /// Each line is split with the value separator (TAB by default)
     /// Sends Message OnSerialValues(string [] values)
     /// </summary>
     public bool NotifyValues = false;
 
     /// <summary>
     /// The values separator.
     /// </summary>
     public char ValuesSeparator = '\t';
 
     //string serialOut = "";
     private List<string> linesIn = new List<string> ();
 
     /// <summary>
     /// Gets the received bytes count.
     /// </summary>
     /// <value>The received bytes count.</value>
     public int ReceivedBytesCount { get { return BufferIn.Length; } }
 
     /// <summary>
     /// Gets the received bytes.
     /// </summary>
     /// <value>The received bytes.</value>
     public string ReceivedBytes { get { return BufferIn; } }
 
     /// <summary>
     /// Clears the received bytes. 
     /// Warning: This prevents line detection and notification. 
     /// To be used when no \n is expected to avoid keeping unnecessary big amount of data in memory
     /// You should normally not call this function if \n are expected.
     /// </summary>
     public void ClearReceivedBytes ()
     {
         BufferIn = "";
     }
 
     /// <summary>
     /// Gets the lines count.
     /// </summary>
     /// <value>The lines count.</value>
     public int linesCount { get { return linesIn.Count; } }
 
     #region Private vars
 
     // buffer data as they arrive, until a new line is received
     private string BufferIn = "";
 
     // flag to detect whether coroutine is still running to workaround coroutine being stopped after saving scripts while running in Unity
     private int nCoroutineRunning = 0;
     #endregion
 
     #region Static vars
 
     // Only one serial port shared among all instances and living after all instances have been destroyed
     private static SerialPort s_serial;
 
     // 
     private static List<Serial> s_instances = new List<Serial> ();
 
     #endregion
 
     void Start ()
     {
         // print ("Serial Start ");
     }
 
     void OnValidate ()
     {
         if (RememberLines < 0)
             RememberLines = 0;
     }
 
     void OnEnable ()
     {
 //        print("Serial OnEnable");
 //        if (s_serial != null)
 //            print ("serial IsOpen: " + s_serial.IsOpen);
 //        else
 //            print ("no serial: ");
 
         s_instances.Add (this);
 
         checkOpen (9600);
 
     }
 
     void OnDisable ()
     {
         //print("Serial OnDisable");
         s_instances.Remove (this);
     }
 
     public void OnApplicationQuit ()
     {
 
         if (s_serial != null) {
             if (s_serial.IsOpen) {
                 print ("closing serial port");
                 s_serial.Close ();
             }
 
             s_serial = null;
         }
 
     }
 
     void Update ()
     {
         //print ("Serial Update");
 
         if (s_serial != null && s_serial.IsOpen) {
             if (nCoroutineRunning == 0) {
                     
                 //print ("starting ReadSerialLoop coroutine");
 
                 // Each instance has its own coroutine but only one will be active a 
                 StartCoroutine (ReadSerialLoop ());
             } else {
                 if (nCoroutineRunning > 1)
                     print (nCoroutineRunning + " coroutines in " + name);
 
                 nCoroutineRunning = 0; 
             }
         }
     }
 
     public IEnumerator ReadSerialLoop ()
     {
 
         while (true) {
 
             if (!enabled) {
                 //print ("behaviour not enabled, stopping coroutine");
                 yield break; 
             }
 
             //print("ReadSerialLoop ");
             nCoroutineRunning++; 
 
             try {
                 while (s_serial.BytesToRead > 0) {  // BytesToRead crashes on Windows -> use ReadLine in a Thread
 
                     string serialIn = s_serial.ReadExisting ();
 
                     // Dispatch new data to each instance
                     foreach (Serial inst in s_instances) {
                         inst.receivedData (serialIn);
                     }
 
                 }
 
             } catch (System.Exception e) {
                 print ("System.Exception in serial.ReadLine: " + e.ToString ());
             }
             
             yield return null;
         }
 
     }
 
     /// return all received lines and clear them
     /// Useful if you need to process all the received lines, even if there are several since last call
     public List<string> GetLines (bool keepLines = false)
     {
 
         List<string> lines = new List<string> (linesIn);
 
         if (!keepLines)
             linesIn.Clear ();
         
         return lines;
     }
     
     /// return only the last received line and clear them all
     /// Useful when you need only the last received values and can ignore older ones
     public string GetLastLine (bool keepLines = false)
     {
         
         string line = "";
         if (linesIn.Count > 0)
             line = linesIn [linesIn.Count - 1];
         
         if (!keepLines)
             linesIn.Clear ();
         
         return line;
     }
 
     public static void Write (string message)
     {
         if (checkOpen ())
             s_serial.Write (message);
     }
 
     public static void WriteLn (string message = "")
     {
         if (s_serial != null && s_serial.IsOpen)
             s_serial.Write (message);
     }
 
 
     /// <summary>
     /// Verify if the serial port is opened and opens it if necessary
     /// </summary>
     /// <returns><c>true</c>, if port is opened, <c>false</c> otherwise.</returns>
     /// <param name="portSpeed">Port speed.</param>
     public static bool checkOpen (int portSpeed = 230400)
     {
 
         if (s_serial == null) {
             
             string portName = "COM58";
             
             if (portName == "") {
                 print ("Error: Couldn't find serial port.");
                 return false;
             } else {
                 //print ("Opening serial port: " + portName);
             }
             
             s_serial = new SerialPort (portName, portSpeed);
             
             s_serial.Open ();
             //print ("default ReadTimeout: " + serial.ReadTimeout);
             //serial.ReadTimeout = 10;
             
             // cler input buffer from previous garbage
             s_serial.DiscardInBuffer ();
 
             
         }
 
         return s_serial.IsOpen;
     }
     
     // Data has been received, do what this instance has to do with it
     protected void receivedData (string data)
     {
 
         if (NotifyData) {
             SendMessage ("OnSerialData", data);
         }
 
         // Detect lines
         if (NotifyLines || NotifyValues) {
         
             // prepend pending buffer to received data and split by line
             string [] lines = (BufferIn + data).Split ('\n');
             
             // If last line is not empty, it means the line is not complete (new line did not arrive yet), 
             // We keep it in buffer for next data.
             int nLines = lines.Length;
             BufferIn = lines [nLines - 1];
             
             // Loop until the penultimate line (don't use the last one: either it is empty or it has already been saved for later)
             for (int iLine = 0; iLine < nLines - 1; iLine++) {
                 string line = lines [iLine];
                 //print(line);
                 
                 // Buffer line
                 if (RememberLines > 0) {
                     linesIn.Add (line);
                         
                     // trim lines buffer
                     int overflow = linesIn.Count - RememberLines;
                     if (overflow > 0) {
                         print ("Serial removing " + overflow + " lines from lines buffer. Either consume lines before they are lost or set RememberLines to 0.");
                         linesIn.RemoveRange (0, overflow);
                     }
                 }
                     
                 // notify new line
                 if (NotifyLines) {
                     SendMessage ("OnSerialLine", line);
                 }
 
                 // Notify values
                 if (NotifyValues) {
                     string [] values = line.Split (ValuesSeparator);
                     SendMessage ("OnSerialValues", values);
                 }
 
             }
         }
     }
 
     static string GetPortName ()
     {
 
         string[] portNames;
 
         switch (Application.platform) {
 
         case RuntimePlatform.OSXPlayer:
         case RuntimePlatform.OSXEditor:
         case RuntimePlatform.OSXDashboardPlayer:
         case RuntimePlatform.LinuxPlayer:
 
             portNames = System.IO.Ports.SerialPort.GetPortNames ();
                 
             if (portNames.Length == 0) {
                 portNames = System.IO.Directory.GetFiles ("/dev/");                
             }
                      
             foreach (string portName in portNames) {                                
                 if (portName.StartsWith ("/dev/tty.usb") || portName.StartsWith ("/dev/ttyUSB"))
                     return portName;
             }                
             return ""; 
 
         default: // Windows
 
             portNames = System.IO.Ports.SerialPort.GetPortNames ();
                     
             if (portNames.Length > 0)
                 return portNames [0];
             else
                 return "COM3";
 
         }
 
     }
 
 }

someone managed to use it? Thank you!

P.S. I'm sure the com port is correct

Comment
Add comment
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

3 Replies

· Add your reply
  • Sort: 
avatar image
3

Answer by GabrielKevers · Apr 29, 2016 at 06:34 AM

use the .NET 2.0 (not subset) Config is into Edit>ProjectSettings>Player>ApiCompatibilityLevel.

Comment
Add comment · Show 1 · 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 jeongcatfish · Aug 31, 2019 at 06:34 AM 0
Share

Hey I'm using Ardity to communicate Serial port and It's works really good when I uses arduino. but It's not working with usb to rs485.

How can I fix this problem? I checked data comes to my computer using serial monitor program.

setting: portName : CO$$anonymous$$6 baudRate 57600

In Unity, Console Log appear "Connection established" but nothing comes up next..

avatar image
3

Answer by Mondkin · Jul 03, 2016 at 04:39 AM

Hello,

A quick solution for using COM ports from Unity is this unitypackage I made, it does all the threading for you. It also comes with some samples to make it easy to use.

(If you have questions please go here: https://github.com/DWilches/SerialCommUnity/issues instead of adding a new comment in this page, as they are easier to track there)

Comment
Add comment · Show 15 · 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 korporeal_games · Sep 16, 2016 at 04:31 PM 0
Share

Any chance you can revive that Unity package $$anonymous$$ondkin? Link doesn't work and i'm chasing down all options for my port sharing issue on OSX El Capitan.

avatar image Mondkin korporeal_games · Sep 16, 2016 at 04:54 PM 0
Share

Hi. Actually, the package is live in GitHub, I just moved it there. Hope you enjoy it! https://github.com/DWilches/SerialCommUnity

avatar image rainisto · Feb 21, 2017 at 12:08 PM 0
Share

Hi @$$anonymous$$ondkin, thank you for the serial package, I've been using it. Perhaps a newbie question but there is a substantial lag that is caused by this now running in a separate thread: I measure something like 30-50 milliseconds from the time of enqueue message to then the serialthread noticing data and starting to writeline it out. The lag varies of course since the threads do not run simultaneously.

Is there any way to reduce this lag? Preferrably down to 0 or as close to it as possible, of course.

avatar image Mondkin rainisto · Feb 22, 2017 at 04:57 AM 0
Share

Hi @rainisto, I'm glad to know the package is being useful for you! About the delay, I can think of two main factors that you might be experiencing: (1) SerialCommUnity reads from your device as often as the Update function of your $$anonymous$$onoBehaviour is being called. That Update function runs once per frame, so if your program runs at 30 FPS, the library will try to read from your device every ~33ms (1 second/30 fps = 0.033s). I don't know how you are doing your delay measurement, but this is a big factor. (2) The default baudrate in my examples is the slowest "standard" value: 9600. Set it to something like 115200 to increase the communication speed. You will also need to change the baud-rate in your piece of hardware to match this. Why did I default to 9600? because though it is the slowest, it's the less error prone (there is less chance of bits being flipped because of network errors, and we are talking here at network protocols without error correction). So if you plan to increase your baudrate, increase it to the lowest value you can get off with! And use only the "standard" values. Here is a list of baudrates and further explanation, in case you are not familiar with the concept.

I hope this is useful!

(I copied your question here as well because it is a very useful question, and I want other people to find it quickly)

avatar image rainisto Mondkin · Feb 22, 2017 at 08:43 AM 0
Share

Thanks @mondkin. Yes, I tried to run it in 115200, and fiddled around with the Windows com port settings even ( http://digital.ni.com/public.nsf/allkb/D776A9D834B132AB86256ED2004E18EF for those that do not know). That can affect up to 15ms. Still the lag was pretty high.

Ultimately since our use case is very real-time critical, this time we ended up using https://roofman.wordpress.com/2012/09/13/fast-serial-communication-for-c-real-time-applications/ - for one reason or another, I didn't have time to fully explore why, we got this to work really quickly indeed.

avatar image Archus · Feb 26, 2017 at 04:41 PM 0
Share

Hi @$$anonymous$$ondkin. Thank you for the serial package. I'm currently trying to use it for my Final Year Project. However, after I imported the package, I noticed that the console returns quite weird error.

Assets/SerialComm/Scripts/SerialThread.cs(245,46): error CS1061: Type System.IO.Ports.SerialPort' does not contain a definition for ReadLine' and no extension method ReadLine' of type System.IO.Ports.SerialPort' could be found (are you missing a using directive or an assembly reference?)

The same error type also appears on the other ReadLine function (line 238) and WriteLine function (line 166). I try to check for this error on your code however I feel that its quite weird because WriteLine and ReadLine is included in the System.IO library and the implementation is correct based on $$anonymous$$SDN (and no other complain). I already changed the project settings to NET 2.0 based on your Github. Did I miss something?

avatar image Mondkin Archus · Feb 26, 2017 at 05:36 PM 0
Share

Yes, that's weird. Which version of Unity are you using?

avatar image Archus Mondkin · Feb 26, 2017 at 07:10 PM 0
Share

I'm currently using Unity Daydream Preview 5.4.2f2-GVR13 (64-bit).

Show more comments
avatar image Ben-BearFish · May 05, 2017 at 06:34 PM 0
Share

@$$anonymous$$ondkin I tried to use SerialPort in Unity 5.6, including the unitypackage you made, but for some reason, no matter what I do, when I call serialPort.Open(), even if I check that the serialport is not open, Unity always throws an IOException that access is denied. I tried CO$$anonymous$$4 and CO$$anonymous$$5, but to no avail. Do you know if there is any solutions for this?

avatar image Mondkin Ben-BearFish · May 06, 2017 at 01:54 AM 0
Share

@Ben-BearFish Is it possible you have the same port already open in another application? That's one of the reasons that can produce that error. If it's not that, I can think of your Windows' user not having privileges to open the port (though it's just a guess)

avatar image Wout_BlinkBlink · May 30, 2017 at 02:57 PM 0
Share

Awesome package - will certainly use it.

About your second comment - Unity can open CO$$anonymous$$ ports with higher numbers, you just have to write them like a different path, in case of your library, write this in the Editor:

 \\.\CO$$anonymous$$11

avatar image Mondkin Wout_BlinkBlink · May 31, 2017 at 02:22 AM 0
Share

Thanks @Wout_BlinkBlink ! I wasn't aware of that different path, I'll update the readme of my repo.

avatar image
0

Answer by RevoltingMuffin · Nov 04, 2016 at 07:09 PM

Please visit the following web site to view updates on this issue and comment letting the Unity staff know how important this functionality is to the COM Port and TTY reading community! VOICE YOU OPINION!

https://issuetracker.unity3d.com/issues/serialport-bytestoread-returns-null-reference

Comment
Add comment · 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

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

12 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

Related Questions

Serial port IOException: access is denied 0 Answers

Need Help Connecting Arduino to Unity 0 Answers

Reading Serial data in Unity from Android app 2 Answers

Unity 5 3D Space Movement Issues 0 Answers

Vertex transforms in custom shader don't work in Unity 5 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