您的位置:首页 > 移动开发 > Unity3D

Unity中使用串口的烦恼

2017-07-08 06:38 253 查看
最近项目使用unity结合串口进行收发通信,使用串口开发过程中,遇到了不解的问题:程序在启动后,进入待机,收到串口的一个字节数据后,执行某项动作(如播放动画),在这个动过过程中,向串口发数据。执行动作完毕进入待机状态,如此循环。串口的收发代码如下:

using UnityEngine;

using System.Collections;

using System;

using System.Threading;

using System.Collections.Generic;

using System.IO.Ports;

using System.IO;

using System.Xml;

public class SerialPortControl : MonoBehaviour {

//定义基本信息
public string serialPortName = "";
public int baudRate;
public Parity parity;
public int dataBits;
public StopBits stopBits;

SerialPort sp = null;
Thread dataReceiveThread;

public static SerialPortControl mInstance;

void InitSerialParas ()
{
string m_URL = Application.dataPath+"/config/serial_paramaters.xml";
if(System.IO.File.Exists(m_URL))
{
XmlDocument XmlDoc = new XmlDocument ();
XmlDoc.Load (m_URL);
serialPortName ="\\\\?\\"+ XmlDoc.GetElementsByTagName("serialPort")[0].ChildNodes[0].InnerText;
baudRate = int.Parse(XmlDoc.GetElementsByTagName("serialPort")[0].ChildNodes[1].InnerText);
if(XmlDoc.GetElementsByTagName("serialPort")[0].ChildNodes[2].InnerText == "none")
parity= Parity.None;
dataBits = int.Parse(XmlDoc.GetElementsByTagName("serialPort")[0].ChildNodes[3].InnerText);
if(XmlDoc.GetElementsByTagName("serialPort")[0].ChildNodes[4].InnerText == "1")
stopBits = StopBits.One;

}else
{
serialPortName ="\\\\?\\"+ "COM3";
baudRate = 9600;
parity= Parity.None;
dataBits = 8;
stopBits = StopBits.One;
}
}
void Awake()
{
mInstance = this;
}

void Start () {
OpenSerialPort ();
dataReceiveThread = new Thread (new ThreadStart (DataReceiveFun));
dataReceiveThread.Start ();
}

void Update () {

//模拟串口发送 0x31 0x32
if (Input.GetKeyDown (KeyCode.Z))
{
byte com = 0x31;
WriteData(com.ToString("X2"));
}

if (Input.GetKeyDown (KeyCode.X))
{
byte com = 0x32;
WriteData(com.ToString("X2"));
}

}
void OnApplicationQuit()
{
ClosePort ();
}
public void ClosePort()
{
try
{
sp.Close();
dataReceiveThread.Abort();

}
catch(Exception ce)
{
Debug.Log (ce.Message);
}
}

public void DataReceiveFun(){
//byte[] buffer = new byte[1];
string str = "";
while(sp!=null && sp.IsOpen)
{
Thread.Sleep(1);
try{
//bytes = sp.Read(buffer,0,1);//接收字节数组
//sp.ReadLine();//接收字符串
//sp.ReadByte();//接收单个字节
byte addr = Convert.ToByte(sp.ReadByte());
str += addr.ToString("X2")+" ";
Debug.Log(str);
MovePlay.mInstance.RevSerialComand(addr);
}
catch(Exception ex)
{
if(ex.GetType()!= typeof(ThreadAbortException))
{
//Debug.Log(ex.Message);
}
}
}

}
public void OpenSerialPort (){

InitSerialParas ();
sp = new SerialPort (serialPortName, baudRate, parity, dataBits, stopBits);
sp.ReadTimeout = 500;
sp.WriteTimeout = 500;
if (!sp.IsOpen) {
try{
sp.Open();

}
catch(Exception ex)
{
Debug.Log (ex.Message);
}
}

}

public void WriteData(string datastr)
{
if (sp.IsOpen) {
sp.Write(datastr);

}
}

}

在运行过程中现象是这样的,使用虚拟串口调试工具测试。

第一次接收串口数据正常,发送数据正常。再进入待机界面,就接收不到串口数据,但是通过手动操作键盘,仍可以发出数据。

经过调整代码:

bytes = sp.Read(buffer,0,1);//接收字节数组

使用Read取得到buffer中,可以实现。使用虚拟串口调试一切正常。

貌似解决了问题。

但是,通过硬件串口连接测试,现象仍然是在发出数据后,串口就收不到数据了,感觉是发送后,占用了串口没有释放……

苦苦寻找没有解决。

最后,通过使用中间件进行了处理。

用VC开发一个中间件和硬件串口进行通信,然后转到UDP和Unity通信,转换通信方式,最后实现了功能。

总结:unity对串口的使用,可能是我操作的不对,也可能是unity本身对串口的操作不是很好导致了这个问题的发生。

希望遇到同样问题的,能够及时跟帖回复,共同学习进步。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息