COM1 and events

Hi all,

I implemented an Library in Mono for Windows to open the COM1 port and receive data from the port.

the following is a simple code sample to open comport and receive data, each time data is reveived an event is fired.

namespace SimpleComPort
{

    public delegate void ComEventHandler(object sender, int value);

    public class SimpleComPort
    {
        static SerialPort _serialport;
        public event ComEventHandler ComValueReceived;
        public Logger.Logger logger;

        
        public SimpleComPort()
        {
            //string[] pns = SerialPort.GetPortNames();
            logger = Logger.Logger.getInstance();
        }

        
        public void ValueReceived(int value)
        {
            ComValueReceived(this, value);
        }

       
        public void OpenComPort(string comport, int baud, System.IO.Ports.Parity parity, int dataBits, StopBits stopbit)
        {
            try
            {
                _serialport = new SerialPort(comport, baud, parity, dataBits, stopbit);
                _serialport.ReadTimeout = 200;
                _serialport.Handshake = Handshake.None;
                _serialport.ErrorReceived += new SerialErrorReceivedEventHandler(_serialport_ErrorReceived);
                _serialport.DtrEnable = true;
                _serialport.DataReceived += new SerialDataReceivedEventHandler(_serialport_DataReceived);
                _serialport.Open();
                logger.ShortLog("Port: " + comport + " open!");
            }
            catch (Exception ex)
            {
                logger.Log(ex);
            }
        }

        
        void _serialport_ErrorReceived(object sender, SerialErrorReceivedEventArgs e)
        {
            logger.Warn("Error while receiving data. "+e.ToString());
        }

        
        void _serialport_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                int b = _serialport.ReadByte();
                ValueReceived(b);
            }
            catch (Exception ex)
            {
                logger.Warn(ex);
            }       
        }
    }
}

now i do in unity:

void Start () {
		SimpleComPort.SimpleComPort scp = new SimpleComPort.SimpleComPort();
		scp.OpenComPort("COM1", 9600, System.IO.Ports.Parity.None, 8, System.IO.Ports.StopBits.One);
		scp.ComValueReceived += new SimpleComPort.ComEventHandler(scp_ComValueReceived);   
	}

void scp_ComValueReceived(object sender, int value)
	{
		Debug.Log("new value "+ value);
		//user_power = value;
	}

But it seems not work, since scp_ComValueReceived(object sender, int value) is not going to be called.

anyone any suggestions??

regards,

omid

Hi, Omid,

I am currently facing the same problem as you are. I am trying to integrate an Arduino board to a simple game to use it as input and output device. I ma basing myself on the code posted at:

http://msmvps.com/blogs/coad/archive/2005/03/23/SerialPort-_2800_RS_2D00_232-Serial-COM-Port_2900_-in-C_2300_-.NET.aspx

I have been able to transmit data from Unity to Arduuino but not from Arduino to Unity for the same reason: the call back method does not get called.
On the other hand I did not implement the code strictly as shown on the link because I had problems when including

using System;
and
using System.Windows.Forms;

It game an error saying that I should have included and assembly library or something. Neither have I been able to add:
[STAThread]
or
Application.Run();

I fear that the problem might be thread related, although I have read somewhere else in the forums that Unity has thread support - or at least something called co-routine. But, I do not know how to use it and how to integrate that with COM communication.
Please, if you have found a solution or if anyone else knows about a solution to this problem, or even if anyone knows there is no solution to this problem, let us know.
Thank you very much.

You may also want to check that Mono properly supports the libraries you are using for the communication. Certain binary compression does not work in Mono, for example, so make sure you check.

Try the most simple setup you can, and if you are using a standard serial port or a USB-Serial UART bridge try to hook up a loopback connection (connect TX to RX) and verify in your Unity app that the bytes are going through.

If you are connecting directly to the Arduino, perhaps write a simple loopback program to do the same thing as connecting TX to RX.

I haven’t played with COM access through Mono/Unity yet, so that’s the most help I can be right now.

-Jeremy

Hi,

I actually got it working using some other C# Serial Port code available at:

http://www.codeproject.com/KB/cs/serialcommunication.aspx

However, perhaps the thread approach would be a better one.
Thanks for the reply.

@scrobby4 - If you don’t mind sharing your code it might be helpful to others as this question has come up a number of times. In fact, this would make a great addition to the wiki: http://www.unifycommunity.com/wiki/index.php?title=Main_Page

Hi,

As a TA for an undergraduate course, I am not allowed to post the solution, because it is part of their homework to find that out, but I can provide the community with a link to the homework itself, which gives the basic code that communicates with Arduino using C#.
The only step missing is to integrate this code into the “update”, “setup” and “end” methods in Unity and define which kind of information you want to send from Arduino to Unity and vice-versa, that is, how your own communication protocol is going to work.
Here is the link for the code:
http://web.cs.wpi.edu/~gogo/courses/imgd3xxx_2009a/projects/proj2/imgd3xxx_Proj2_SerialComm_ArduinoSide.zip

And the project that student have to implement:
http://web.cs.wpi.edu/~gogo/courses/imgd3xxx_2009a/projects/proj2/

I hope this is of some help.
Best,

Hello,
Did anyone ever get serial communication on working in Unity on Windows and is able to post a code snippet?
My understanding is that to make it work I need to create a Mono Library first using something like MonoDevelop - is this correct?

Cheers

J

Hi,

Here is the basic structure I used for connecting Arduino with Unity using the serial port. It is pretty simple as you can see. I hope this helps:

//Basic libraries
using UnityEngine;
using System.Collections;
#region Using directives

//Other libraries
using System;
using System.Collections.Generic;
using System.ComponentModel;

//Serial Port library.
using System.IO.Ports;

#endregion

public class MyClass : MonoBehaviour {
	
	//-----
	// Some other variable definition code 
        // could be added in here.
	//-----
	private SerialPort sp;
	
	// Use this method for initialization.
	void Start () {
		
		//-----
		// Inialization of other variables in here.
		//-----

		// Port set up with some basic settings. 
                // In my case, my device (Arduino) 
                // was in Port COM4 with a baud rate of 9600.
		sp = new SerialPort( "COM4"
                                   , 9600
                                   , Parity.None
                                   , 8
                                   , StopBits.One); 
	
		// Open the port for communications 
		sp.Open(); 

	        // Set read time out to 50 ms.
                // This value might be too high actually.
	        sp.ReadTimeout = 50;
		
	}

	void End() {

		// Closes the port - this does not 
                // seem to work for me. 
		// Perhaps it should be placed elsewhere.
		sp.Close(); 
		
	}

	// Update is called once per frame
	void FixedUpdate() {

		// The code implements a polling 
                // system, that is, data is 
		// only sent to Unity when requested.

		// Writes to the serial port. 
                // As an example I am asking for 
                // the x coordinate of a joystick 
                // implemented using Arduino.
                // However, for joysticks it might 
                // be better to use streaming instead.

        	sp.WriteLine("jx");


        	// Reads data sent from Arduino 
                //through the serial port.

        	string tempS = sp.ReadLine();

		//-----
		// Process the data received and apply 
                // it in a useful manner.
		//-----
		
	}
}

Best.

Fantastic! That’s really helpful. The good news is that I’ve got it working on Unity Indy. There’s no need for external libraries which is what I feared.

The bad news for others trying this is that Mono’s handling of serial ports is a bit flaky which I suspect is why Unity doesn’t document these classes.
Essentially I found two problems:

  • Serial events don’t work
  • Functions which are supposed to return a particular value if there’s no data don’t work- they just give a timeout exception.
    The way I got round this is by catching the exception and ignoring it - seems to work fine. Here’s an example using ReadByte but I’ve also had it working using ReadLine.
//Basic libraries
using UnityEngine;
using System.Collections;
#region Using directives

//Other libraries
using System;
using System.Collections.Generic;
using System.ComponentModel;

//Serial Port library.
using System.IO.Ports;

#endregion

public class ComTest : MonoBehaviour {
   
   //-----
   // Some other variable definition code
        // could be added in here.
   //-----
   private SerialPort sp;
   
   // Use this method for initialization.
   void Start () {
      
      //-----
      // Inialization of other variables in here.
      //-----

      // Port set up with some basic settings.
               
                // was in Port COM1 with a baud rate of 9600.
      sp = new SerialPort( "COM1"
                                   , 9600
                                   , Parity.None
                                   , 8
                                   , StopBits.One);
   
      // Open the port for communications
      sp.Open();

           // Set read time out to 50 ms.
                // This value might be too high actually.
           sp.ReadTimeout = 50;
      
   }

   void OnApplicationQuit() {

      // Closes the port - this does not
                // seem to work for me.
      // Perhaps it should be placed elsewhere.
      sp.Close();
      
   }

   // Update is called once per frame
   void FixedUpdate() {

     
              // Read serial port data
			// Mono serial class doesn't implement serial events or give the correct
	       // response to no data available
	       // If there's no data it throws a timeout error so we catch that error and do nothing
			string tempS = "";
        
	   try {
	     byte tempB =  (byte) sp.ReadByte();
		   while (tempB != 255) {
			   tempS += ((char) tempB);
			   tempB = (byte) sp.ReadByte();
		   }
	   } 
	   catch (Exception e) {
		   
	   }
	    if (tempS!="") {
			  Debug.Log("serial out "+tempS);
		   }
	   
	 
      
   }
}

Hi,

I read this post before, when I was starting my project.
the code here didn’t help much though, which is mostly because there is no arduino script displayed.

I’ve posted my solution on google code as an open source project here:

http://code.google.com/p/unity-arduino-serial-connection

It allows windows PC’s to use a direct connection. A mac implementation with serialproxy is on the way.

I also listed it here:
http://forum.unity3d.com/viewtopic.php?t=51433

I hope this helps somebody.

1 Like

hi,
can u post the code snippet working using ReadLine…
thx

I posted some code over here that I use to connect Arduino/Unity with bluetooth. It’s super simple and it uses ReadLine… maybe this will help…
http://stackoverflow.com/a/16502886/2373973

Hi, the problem is because .NET 2.0 Subset
Change for .Net 2.0

In
Edit/Project Settings/Player/Other Settings/Optimization/Api Compatibility Level: .NET 2.0.
/// Era .NET 2.0 Subset

I found a alternative temporal solution for this, please read the following thread:

i need package serialport for unity3d platform android .
i error when run on tablet android project unity
error monoposixhelper.dll