Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

COM1 and events

Discussion in 'Scripting' started by Omid, Nov 7, 2008.

  1. Omid

    Omid

    Joined:
    Nov 7, 2008
    Posts:
    10
    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.


    Code (csharp):
    1.  
    2. namespace SimpleComPort
    3. {
    4.  
    5.     public delegate void ComEventHandler(object sender, int value);
    6.  
    7.     public class SimpleComPort
    8.     {
    9.         static SerialPort _serialport;
    10.         public event ComEventHandler ComValueReceived;
    11.         public Logger.Logger logger;
    12.  
    13.        
    14.         public SimpleComPort()
    15.         {
    16.             //string[] pns = SerialPort.GetPortNames();
    17.             logger = Logger.Logger.getInstance();
    18.         }
    19.  
    20.        
    21.         public void ValueReceived(int value)
    22.         {
    23.             ComValueReceived(this, value);
    24.         }
    25.  
    26.        
    27.         public void OpenComPort(string comport, int baud, System.IO.Ports.Parity parity, int dataBits, StopBits stopbit)
    28.         {
    29.             try
    30.             {
    31.                 _serialport = new SerialPort(comport, baud, parity, dataBits, stopbit);
    32.                 _serialport.ReadTimeout = 200;
    33.                 _serialport.Handshake = Handshake.None;
    34.                 _serialport.ErrorReceived += new SerialErrorReceivedEventHandler(_serialport_ErrorReceived);
    35.                 _serialport.DtrEnable = true;
    36.                 _serialport.DataReceived += new SerialDataReceivedEventHandler(_serialport_DataReceived);
    37.                 _serialport.Open();
    38.                 logger.ShortLog("Port: " + comport + " open!");
    39.             }
    40.             catch (Exception ex)
    41.             {
    42.                 logger.Log(ex);
    43.             }
    44.         }
    45.  
    46.        
    47.         void _serialport_ErrorReceived(object sender, SerialErrorReceivedEventArgs e)
    48.         {
    49.             logger.Warn("Error while receiving data. "+e.ToString());
    50.         }
    51.  
    52.        
    53.         void _serialport_DataReceived(object sender, SerialDataReceivedEventArgs e)
    54.         {
    55.             try
    56.             {
    57.                 int b = _serialport.ReadByte();
    58.                 ValueReceived(b);
    59.             }
    60.             catch (Exception ex)
    61.             {
    62.                 logger.Warn(ex);
    63.             }      
    64.         }
    65.     }
    66. }
    67.  
    68.  
    now i do in unity:


    Code (csharp):
    1.  
    2.  
    3. void Start () {
    4.         SimpleComPort.SimpleComPort scp = new SimpleComPort.SimpleComPort();
    5.         scp.OpenComPort("COM1", 9600, System.IO.Ports.Parity.None, 8, System.IO.Ports.StopBits.One);
    6.         scp.ComValueReceived += new SimpleComPort.ComEventHandler(scp_ComValueReceived);  
    7.     }
    8.  
    9. void scp_ComValueReceived(object sender, int value)
    10.     {
    11.         Debug.Log("new value "+ value);
    12.         //user_power = value;
    13.     }
    14.  
    But it seems not work, since scp_ComValueReceived(object sender, int value) is not going to be called.

    anyone any suggestions??

    regards,

    omid
     
  2. scrobby4

    scrobby4

    Joined:
    Sep 3, 2009
    Posts:
    9
    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/archiv...32-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.
     
  3. jeremyace

    jeremyace

    Joined:
    Oct 12, 2005
    Posts:
    1,661
    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
     
  4. scrobby4

    scrobby4

    Joined:
    Sep 3, 2009
    Posts:
    9
  5. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
  6. scrobby4

    scrobby4

    Joined:
    Sep 3, 2009
    Posts:
    9
    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...oj2/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,
     
  7. Harissa

    Harissa

    Joined:
    Nov 13, 2008
    Posts:
    138
    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
     
  8. scrobby4

    scrobby4

    Joined:
    Sep 3, 2009
    Posts:
    9
    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:

    Code (csharp):
    1. //Basic libraries
    2. using UnityEngine;
    3. using System.Collections;
    4. #region Using directives
    5.  
    6. //Other libraries
    7. using System;
    8. using System.Collections.Generic;
    9. using System.ComponentModel;
    10.  
    11. //Serial Port library.
    12. using System.IO.Ports;
    13.  
    14. #endregion
    15.  
    16. public class MyClass : MonoBehaviour {
    17.    
    18.     //-----
    19.     // Some other variable definition code
    20.         // could be added in here.
    21.     //-----
    22.     private SerialPort sp;
    23.    
    24.     // Use this method for initialization.
    25.     void Start () {
    26.        
    27.         //-----
    28.         // Inialization of other variables in here.
    29.         //-----
    30.  
    31.         // Port set up with some basic settings.
    32.                 // In my case, my device (Arduino)
    33.                 // was in Port COM4 with a baud rate of 9600.
    34.         sp = new SerialPort( "COM4"
    35.                                    , 9600
    36.                                    , Parity.None
    37.                                    , 8
    38.                                    , StopBits.One);
    39.    
    40.         // Open the port for communications
    41.         sp.Open();
    42.  
    43.             // Set read time out to 50 ms.
    44.                 // This value might be too high actually.
    45.             sp.ReadTimeout = 50;
    46.        
    47.     }
    48.  
    49.     void End() {
    50.  
    51.         // Closes the port - this does not
    52.                 // seem to work for me.
    53.         // Perhaps it should be placed elsewhere.
    54.         sp.Close();
    55.        
    56.     }
    57.  
    58.     // Update is called once per frame
    59.     void FixedUpdate() {
    60.  
    61.         // The code implements a polling
    62.                 // system, that is, data is
    63.         // only sent to Unity when requested.
    64.  
    65.         // Writes to the serial port.
    66.                 // As an example I am asking for
    67.                 // the x coordinate of a joystick
    68.                 // implemented using Arduino.
    69.                 // However, for joysticks it might
    70.                 // be better to use streaming instead.
    71.  
    72.             sp.WriteLine("jx");
    73.  
    74.  
    75.             // Reads data sent from Arduino
    76.                 //through the serial port.
    77.  
    78.             string tempS = sp.ReadLine();
    79.  
    80.         //-----
    81.         // Process the data received and apply
    82.                 // it in a useful manner.
    83.         //-----
    84.        
    85.     }
    86. }
    Best.
     
  9. Harissa

    Harissa

    Joined:
    Nov 13, 2008
    Posts:
    138
    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.

    Code (csharp):
    1. //Basic libraries
    2. using UnityEngine;
    3. using System.Collections;
    4. #region Using directives
    5.  
    6. //Other libraries
    7. using System;
    8. using System.Collections.Generic;
    9. using System.ComponentModel;
    10.  
    11. //Serial Port library.
    12. using System.IO.Ports;
    13.  
    14. #endregion
    15.  
    16. public class ComTest : MonoBehaviour {
    17.    
    18.    //-----
    19.    // Some other variable definition code
    20.         // could be added in here.
    21.    //-----
    22.    private SerialPort sp;
    23.    
    24.    // Use this method for initialization.
    25.    void Start () {
    26.      
    27.       //-----
    28.       // Inialization of other variables in here.
    29.       //-----
    30.  
    31.       // Port set up with some basic settings.
    32.                
    33.                 // was in Port COM1 with a baud rate of 9600.
    34.       sp = new SerialPort( "COM1"
    35.                                    , 9600
    36.                                    , Parity.None
    37.                                    , 8
    38.                                    , StopBits.One);
    39.    
    40.       // Open the port for communications
    41.       sp.Open();
    42.  
    43.            // Set read time out to 50 ms.
    44.                 // This value might be too high actually.
    45.            sp.ReadTimeout = 50;
    46.      
    47.    }
    48.  
    49.    void OnApplicationQuit() {
    50.  
    51.       // Closes the port - this does not
    52.                 // seem to work for me.
    53.       // Perhaps it should be placed elsewhere.
    54.       sp.Close();
    55.      
    56.    }
    57.  
    58.    // Update is called once per frame
    59.    void FixedUpdate() {
    60.  
    61.      
    62.               // Read serial port data
    63.             // Mono serial class doesn't implement serial events or give the correct
    64.            // response to no data available
    65.            // If there's no data it throws a timeout error so we catch that error and do nothing
    66.             string tempS = "";
    67.        
    68.        try {
    69.          byte tempB =  (byte) sp.ReadByte();
    70.            while (tempB != 255) {
    71.                tempS += ((char) tempB);
    72.                tempB = (byte) sp.ReadByte();
    73.            }
    74.        }
    75.        catch (Exception e) {
    76.            
    77.        }
    78.         if (tempS!="") {
    79.               Debug.Log("serial out "+tempS);
    80.            }
    81.        
    82.      
    83.      
    84.    }
    85. }
     
  10. daft

    daft

    Joined:
    Mar 24, 2010
    Posts:
    6
    YaNakajima likes this.
  11. shrek

    shrek

    Joined:
    Oct 27, 2011
    Posts:
    1
    hi,
    can u post the code snippet working using ReadLine...
    thx
     
  12. KrisCadle

    KrisCadle

    Joined:
    May 19, 2011
    Posts:
    2
  13. azueta9

    azueta9

    Joined:
    Jan 26, 2014
    Posts:
    2
    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
     
  14. patricioaljndro

    patricioaljndro

    Joined:
    Mar 6, 2014
    Posts:
    12
  15. qmtco

    qmtco

    Joined:
    May 31, 2015
    Posts:
    1
    i need package serialport for unity3d platform android .
    i error when run on tablet android project unity
    error monoposixhelper.dll