Unity中的C#SerialPort EventHandler [英] C# SerialPort EventHandler in Unity

查看:93
本文介绍了Unity中的C#SerialPort EventHandler的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为Unity编写C#代码.只是在EventHandler中读取SerialPort值.问题是未调用处理程序.这是代码

I am writing C# code for Unity. Just reading SerialPort value in EventHandler. The problem is that the handler is not called. here's the code

using UnityEngine;
using System.Collections;
using System;
using System.IO.Ports;

public class MainScript : MonoBehaviour {

public SerialPort mySerialPort;
public static float speed=100;
GameObject cube ;
public GUIStyle style ;
// Use this for initialization
void Start () {

    cube = GameObject.FindGameObjectWithTag ("cube");

    if(mySerialPort.IsOpen)
        mySerialPort.Close();

    mySerialPort = new SerialPort("com5");
    mySerialPort.BaudRate = 9600;
    mySerialPort.Parity = Parity.None;
    mySerialPort.StopBits = StopBits.None;
    mySerialPort.DataBits = 8;
    mySerialPort.Handshake = Handshake.None;
    mySerialPort.DataReceived += new SerialDataReceivedEventHandler (DataReceivedHandler);

    if(mySerialPort.IsOpen == false)
        mySerialPort.Open();
}


void OnGUI(){
    GUI.Box (new Rect(100,100,100,100),"Speed : " + speed , style);
}
// Update is called once per frame
void Update () {
// speed = mySerialPort.ReadTo ("\r");
// update My View with the speed new value

    cube.transform.Rotate(Vector3.up * speed *Time.deltaTime);

}


public static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
    SerialPort sp = (SerialPort)sender;
    speed = float.Parse( sp.ReadTo ("\r") ) ;
    print ("Data Recieved : " + speed);
}
}

问题不在串行端口中,因为当我在统一更新功能中读取它时,它读取了正确的值,但是在更新UI时存在性能问题.

the problem is not in the serial port as, when i read it in the update function for unity it reads the right value but, there's a performance issue updating the UI.

谢谢

推荐答案

正如您所说,不会调用"DataReceived"事件的处理程序,这是Unity的已知问题(截至今天).我的解决方法是使用单独的线程读取端口(轮询):

As you said, the handler for 'DataReceived' event would not be called and it's a known issue with Unity (as of today). My workaround was to use a separate thread to read the port (polling):

private bool _looping;
private SerialPort _port;
public string _comPort; // e.g. "COM3"
private const int _baudRate = 921600;
private Thread portReadingThread;
private string strData;

private void OnEnable()
{
    _looping = true;
    portReadingThread = new Thread(ReadArduino);
    portReadingThread.Start();
}

private void OnDestroy()
{
    _looping = false;  // This is a necessary command to stop the thread.
                       // if you comment this line, Unity gets frozen when you stop the game in the editor.                           
    portReadingThread.Join();
    portReadingThread.Abort();
    _port.Close();
}

void ReadArduino()
{        
    // For any COM number larger than 9, you should add prefix of \\\\.\\ to it. 
    // For example for COM15, you should write it as "\\\\.\\COM15" instead of "COM15".
    _port = new SerialPort(_comPort, _baudRate);
    if (_port == null)
    {
        Debug.LogError("_port is null");
        return;
    }

    _port.Handshake = Handshake.None;
    _port.DtrEnable = true;
    //myPort.RtsEnable = true;
    _port.ReadTimeout = 500; // NOTE: Don't Reduce it or the communication might break!
    _port.WriteTimeout = 1000;
    _port.Parity = Parity.None;
    _port.StopBits = StopBits.One;
    _port.DataBits = 8;
    _port.NewLine = "\n";

    _port.Open();
    if (!_port.IsOpen)
        print("PORT HAS NOT BEEN OPEN!");
    // Send "START" command to the arduino.
    _port.WriteLine("START");
    // Start reading the data coming through the serial port.
    while (_looping)
    {
        strData = _port.ReadLine(); // blocking call.
        print(strData);
        Thread.Sleep(0);
    }
}

读取发生在以下行:

strData = _port.ReadLine(); // blocking call.

但它不会阻止或冻结统一性,因为它发生在单独的线程中.

but it does not block or freeze unity because it's happening in a separate thread.

顺便说一句,如果您想向端口中写入一些内容,只需编写:

By the way, if you wanted to write something to the port, simply write:

  public void WriteToArduino()
  {
        _port.WriteLine("YourMessageHere");
  }

您可以在游戏中的任何位置调用WriteToArduino().不需要在任何特殊的线程之内.

You can call WriteToArduino() anywhere in your game. It does not need to be in any special thread or something.

这篇关于Unity中的C#SerialPort EventHandler的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆