Hello, I am here to present an alternative to using serial ports on Unity, this is only an approximation to the final resolution of this problem. I hope to be helpful.
First apologize for my bad English.
Background:
Some time ago I faced with the problem of handling serial ports within unity, fails to read the data properly but I can send them. Researching I realized that the problem arises with an event data management, this enables notify the system when data is received, if we try to read otherwise errors can occur because our algorithm can not be synchronized with the data sent from the device serial port, for example the famous âthe Operation has timeoutâ. this event is called âSerialDataReceivedEventHandlerâ ( Represents the method that will handle the data received event of a Serial Port object.)
This method does not seem to be implemented in unity by what I have seen in many forums
NOTE: Iâm using a PIC serial board but I guess this works also with Arduino both use the standard UART (universal asynchronous receiver/transmitter) for serial communications.
ALTERNATIVES
Well now I want to share a good solution I found, below I submit a temporary alternative solution as a developer I want to create my own.
One day I read about a plugin for unity ,particularly one external DLL. I used the shortest route and downloaded a commercial serial component called âComponent Activexperts Serial Portâ, you can try it for 30 days.
The component made me realize I can make a correct handling of serial ports through of dynamic link libraries (DLL) and is probably the best way.
thatâs why I want to create my own DLL to handle serial ports, I have been researching and apparently I have to learn c ++ and Win32.
Well, I would like to show you an example of how to use this component serial port if anyone can get the paid version.
First we download the serial component of this link: ActiveXperts Software - download page
(We installed it as a typical program)
Once installed we go to the installation folder C: \ Program Files \ ActiveXperts \ Serial Port Component \ Samples
In this location will find examples, we go to the âVisual CSharp.NETâ folder and look for into any project the dll file âInterop.AxSerialâ Visual inside the folder âAny CPUâ and copy this file.
Paste the file in your project and after at the following location: âC: \ Program Files \ Unity \ Editorâ.
NOTE: Currently Iâm using Unity 5 free version (Last Update)
Now we need to install a free package that allows you to use coroutines as asynchronous thread named Thread Ninja - Multithread Coroutine
Link: The Best Assets for Game Making | Unity Asset Store
The idea is not to use the update method as this will down the performance so it is best to use a method that act as an update method that runs every so often (seconds), not every frame so it is very fast. So we update data received from the port ,for example, every 1 second .
And when we have the package installed and pasting dll file in its respective location, create a class (in the same location Interop.AxSerial) location such as:
(This is an algorithm that requires a lot of improvement)
using UnityEngine;
using System.Collections;
using AxSerial;//Import the DLL external class
using System;
using System.IO;
using System.Threading;
using CielaSpike;//Import the custom thread for unity
public SerialController : MonoBehaviour {
ComPort objComport;//Serial port object
//string of data received for the serial port
string datareceived="";
/*
*method that initializes the serial port
*/
void initComponents()
{
try
{
objComport = new ComPort();
objComport.Device="COM7";//this specifies own port
objComport.BaudRate = 9600;
objComport.Open();//Open the port
}
catch(Exception ex)
{
Debug.Log(ex.GetBaseException());
}
}
void Start()
{
initComponents();
if (objComport.IsOpened)
{
StartCoroutine("manage_data");//Start coroutine for manage the data
Debug.Log("Port opened");
}
else
{
Debug.Log("Could not to open the port");
}
}
void OnDestroy
{
try
{
objComport.Close();
}
catch(Exception ex)
{
Debug.Log(ex.GetBaseException());
}
}
/*
* asynchronous coroutine,
* the idea is that the method of getting data is executing every so often, for example each one second.,
* not for each frame like the Update method because this would down the performance
*
*/
IEnumerator manage_data()
{
this.StartCoroutineAsync(Blocking(), out task);
yield return StartCoroutine(task.Wait());
}
IEnumerator Blocking()
{
int sleep = int.MaxValue;
//test cycle, I tried with the while cicle but it crashes Unity,
// when this "for" cicle is executing , it reads data and prints them almost in sync when the serial device sends data
//If you have a best idea, please share !!!
for (int i = 0; i <= int.MaxValue; i++)
{
read_data();
//wait 0.5 seconds and read again
yield return new WaitForSeconds(0.5F);
}
Thread.Sleep(sleep);
}
/*
*Read the data from the serial port
*/
void read_data()
{
if (objComport.LastError == 0)
{
datareceived=objComport.ReadString();
//Print data on Console
print( "Data Received: " +datareceived)
}
else
{
Debug.Log("No data");
}
}
}
This algorithm is not perfect, itâs just a suggestion for handling serial ports. Any suggestions, better idea, please sharing.
As I said the idea is to create your own free dll component.
bibliography:
I hope ti helps:
ActiveXperts Serial Port Component Manual
How To Work With C # Serial Port Communication
Serial Communications: The Way .NET
Serial Communications in Win32
Coroutines vs Update
Serial library for C ++
DLL Tutorial For Beginners
http://www.codeguru.com/cpp/cpp/cpp_mfc/tutorials/article.php/c9855/DLL-Tutorial-For-Beginners.htm