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本身对串口的操作不是很好导致了这个问题的发生。
希望遇到同样问题的,能够及时跟帖回复,共同学习进步。
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本身对串口的操作不是很好导致了这个问题的发生。
希望遇到同样问题的,能够及时跟帖回复,共同学习进步。
相关文章推荐
- Unity 安卓下使用串口提示:System.DllNotFoundException: MonoPosixHelper的解决办法
- Unity中使用串口的注意事项
- VB使用API实现串口通讯的异常问题
- VB串口使用心得两则
- 使用虚拟串口软件实现单机进行串口通信调试
- 使用SerialPort类设计串口通讯程序
- 使用Win32 API创建串口通讯程序
- 使用SerialPort类设计串口通讯程序
- 如何使用串口控件MSComm在dotNet下编程
- FC6 中串口不能正常使用的原因与解决办法
- 串口(SATA)硬盘如何使用GHOST
- 使用串口发送普通短消息
- 一个使用Java读取串口的程序
- .NET中的串口使用
- vmware中串口使用
- Linux下使用Qtopia时鼠标和串口冲突问题
- [翻译] 第四章,高级串口编程 - 使用 ioctl 和 select
- 串口(SATA)硬盘如何使用GHOST
- VB6使用API实现串口通信
- 串口调试精灵的使用和串口程序调试技巧