• Unity读取串口数据

    2018-05-05 12:59:57
    读取串口数据的过程其实就跟你读取文件操作IO时的过程差不多:首先要使用using System.IO.Ports;时需要先将 改为 具体操作: Edit -> Project Settings -> Player -> Other Settings -> Api Compatibility ...

    读取串口数据的过程其实就跟你读取文件操作IO时的过程差不多:

    首先要使用using System.IO.Ports;时需要先将
    这里写图片描述
    改为
    这里写图片描述

    具体操作: Edit -> Project Settings -> Player -> Other Settings -> Api Compatibility Level

    具体代码

    using System.Collections;
    using System.Collections.Generic;
    using System.Threading;
    using UnityEngine;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.IO.Ports;
    using System.Text.RegularExpressions;
    using System.Text;
    using System;
    
    public class Mpu6050 : MonoBehaviour {
    
        public GameObject target;//目标操作物体
        private SerialPort sp;
        private Thread recvThread;//线程
        float x, y, z, buttonState = 0, sensorValue = 0;//存放欧拉角  
    
        // Use this for initialization   
        void Start()
        {
            sp = new SerialPort("COM3", 115200, Parity.None, 8, StopBits.One);
            //串口初始化  
            if (!sp.IsOpen)
            {
                sp.Open();
            }
            recvThread = new Thread(ReceiveData); //该线程用于接收串口数据  
            recvThread.Start();
        }
        void Update()
        {
            //...
        }
    
        private void ReceiveData()
        {
            try
            {
                string s = "";
                //以行的模式读取串口数据
                while ((s = sp.ReadLine()) != null)
                {
                    print(s); //打印读取到的每一行数据
                }
            }
            catch (Exception ex)
            {
                Debug.Log(ex);
            }
        }
    
        void OnApplicationQuit()
        {
            sp.Close();//关闭串口
        }
    
    }
    

    当然使用此代码时需要注意你串口数据需要以一行一行的形式进行传输。

    展开全文
  • unity 3D接收数据

    2020-05-25 23:30:45
    unity3D接收串口数据,能够按照协议,接收下位机传的数据。
  • 最近要在Unity3D中与单片机串口通信,unity3D我本就是新手,这里自己摸索加网上资料最后终是弄好了,这里是最简单直接的步骤。
  • 近期用到串口,遇到的一些坑,记录一下。先看代码: using System; using System.Collections; using System.Collections.Generic; using System.IO.Ports; using System.Text; using System.Threading; ...

    近期用到串口,遇到的一些坑,记录一下。先看代码:

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.IO.Ports;
    using System.Text;
    using System.Threading;
    using System.Xml;
    using UnityEngine;
    
    public class RecieveSport : MonoBehaviour
    {
        public SerialPort port = null;
        private Thread tPort = null;
        private bool canRecieveMsg = true;
        public static RecieveSport _instance;
        public string tempMsg = "";
    
        public List<byte> listReceive = new List<byte>();
        string str;
        char[] strchar = new char[100];//接收的字符信息转换为字符数组信息
        // Use this for initialization
        void Start()
        {
            if (_instance == null)
            {
                _instance = this;
            }
            port = new SerialPort();
            OpenPort(LoadXml());
    
        }
        string LoadXml()
        {
            //创建xml文档
            XmlDocument xml = new XmlDocument();
            xml.Load(System.IO.Directory.GetCurrentDirectory() + "\\IP.xml");
            //得到objects节点下的所有子节点
            XmlNodeList xmlNode = xml.SelectSingleNode("HeadSelect").ChildNodes;
            //Debug.Log(((XmlElement)xmlNode[2]).GetAttributeNode("com").Value.ToString());
            //遍历所有子节点
            return ((XmlElement)xmlNode[2]).GetAttributeNode("com").Value.ToString();
    
        }
        // Update is called once per frame
        void Update()
        {
        }
        public bool OpenPort(string portName)
        {
            if (this.port != null && this.port.IsOpen == false)
            {
                try
                {
                    this.port = new SerialPort(portName, 9600);
                    this.port.ReadTimeout = 500;
                    this.port.WriteTimeout = 500;
                    this.port.Open();
    
                    this.tPort = new Thread(new ThreadStart(PortReceive));
                    this.tPort.IsBackground = true;
                    this.tPort.Start();
                    return true;
                }
                catch (Exception err)
                {
                    throw err;
                }
            }
            else
            {
                throw new System.Exception("串口已经打开");
            }
        }
    
        void OnApplicationQuit()
        {
            canRecieveMsg = false;
        }
        void PrintData()
        {
            for (int i = 0; i < listReceive.Count; i++)
            {
                strchar[i] = (char)(listReceive[i]);
                str = new string(strchar);
            }
            Debug.Log(str);
            listReceive.Clear();
        }
        /// <summary>
        /// 按字节进行读取,每次读一个字节存放在List里,
        /// </summary>
        void DataReceive()
        {
            while (port != null && port.IsOpen)
            {
                Thread.Sleep(500);
                try
                {
                    byte addr = Convert.ToByte(port.ReadByte());
                    port.DiscardInBuffer();
                    listReceive.Add(addr);
                    PrintData();
                }
                catch
                {
                    //listReceive.Clear();
                }
            }
        }
        /// <summary>
        /// 可以读取多个字符,即字节数组;但是需要的平台的是.net 4.6
        /// 将 Scripting Runing Vision 和Api Compatibility都改为.Net 4.6
        /// </summary>
        private void PortReceive()
        {
    
            try
            {
                while (canRecieveMsg)
                {
    
                    Thread.Sleep(25);//这行是设定读取间隔,可以根据需要不使用
                    if (!port.IsOpen)
                        return;
                    int datalength = port.BytesToRead;
                    if (datalength == 0)
                    {
                        continue;
                    }
                    int i = 0;
                    StringBuilder sb = new StringBuilder();
                    while (i < datalength)
                    {
                        byte[] ds = new byte[1];
                        int len = port.Read(ds, 0, 1);
                        sb.Append(Encoding.UTF8.GetString(ds, 0, len));
                        i += len;
                    }
                    Debug.Log(sb.ToString());
                    //ProcessMsg(sb.ToString());
                    //这里sb就是串口获取的数据
                }
            }
            catch { }
        }
    
        public void DataSend(string data)
        {
            port.Write(data);
        }
        private void OnGUI()
        {
            string test = "woshinibaba";
            if(GUILayout.Button("SendMessage"))
            {
                DataSend(test);
            }
        }
    }
    
    

    补充:XML文档

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <HeadSelect>
      <IP ip="192.168.xx.xx">
      </IP>
      <PORT port="8631">
      </PORT>
      <COM com="COM2">
      </COM>
    </HeadSelect>
    
    

    坑在代码里也注释了,
    1、接收多个字符的时候代码运行环境和api应该是.net4.6。
    2、还有就是Read()方法不会一次读完
    3、线程的Sleep()方法是为了匹配程序的执行速度和返回速度。
    tisp:代码复制即可运行。如果又说错的地方,欢迎指正!

    展开全文
  • 一、前言 记得以前写了一篇Unity3D与串口通信程序的开发的...但是最近有小伙伴问我如何接收串口程序,今天就再分享一下比较完整的Unity开发的串口通信程序吧,包括发送与接收数据,绑定串口号等。 二、文章链接 ...

    一、前言

    记得以前写了一篇Unity3D与串口通信程序的开发的文章,主要讲的是如何用Unity3D程序给串口发送数据,具体可以查看这篇文章https://blog.csdn.net/q764424567/article/details/78710739
    但是最近有小伙伴问我如何接收串口程序,今天就再分享一下比较完整的Unity开发的串口通信程序吧,包括发送与接收数据,绑定串口号等。

    二、文章链接

    Unity3d 与串口的通信程序的开发,软件硬件结合
    【Unity3D日常】Unity3d与串口通信程序的开发

    三、正文

    1、先做一个UI界面吧
    在这里插入图片描述
    在这里插入图片描述
    做的比较简单,就不多数哦了

    2、代码

    using UnityEngine;
    using System.IO.Ports;
    using System.Text;
    using UnityEngine.UI;
    
    public class SerialPortTest : MonoBehaviour
    {
        private SerialPort sp = new SerialPort();
        public Text m_TextSendDataPar;
        public Text m_TextShowData;
    
        // Use this for initialization
        void Start()
        {
            //打开串口
            Init("COM1", 9600, Parity.None, 8, StopBits.None);
        }
    
        //发送数据按钮
        public void Btn_SendData()
        {
            Data_Send(m_TextSendDataPar.ToString());
        }
    
        //初始化串口类
        public void Init(string _portName,int _baudRate,Parity _parity,int dataBits,StopBits _stopbits)
        {
            sp = new SerialPort(_portName, _baudRate, _parity, dataBits, _stopbits);//绑定端口
            sp.DataReceived += new SerialDataReceivedEventHandler(Data_Received);//订阅委托
        }
    
        //接收数据
        private void Data_Received(object sender, SerialDataReceivedEventArgs e)
        {
            byte[] ReDatas = new byte[sp.BytesToRead];
            sp.Read(ReDatas, 0, ReDatas.Length);//读取数据
            this.Data_Show(ReDatas);//显示数据
        }
    
        /// <summary>
        /// 显示数据
        /// </summary>
        /// <param name="data">字节数组</param>
        public void Data_Show(byte[] data)
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < data.Length; i++)
            {
                sb.AppendFormat("{0:x2}" + "", data[i]);
            }
            Debug.Log(sb.ToString());
            m_TextShowData.text = sb.ToString();
        }
    
        //发送数据
        public void Data_Send(string _parameter)
        {
            sp.Open();
            sp.WriteLine(_parameter);
            sp.Close();
        }
    }
    
    

    3、绑定参数
    在这里插入图片描述
    在这里插入图片描述
    4、找不到命名空间的问题

    在unity 引用System.IO.Ports 却发现引用不到 查了一下才看到 要在[Edit->Project Settings->Player]下,修改[Other Settings]下的[Optimization]的[API Compatibility Level]为[.NET 2.0](默认为[.NET 2.0 Subset]。才能找到
    *PS:感谢单曲循环小盆友的提醒
    在这里插入图片描述

    OK了。。。小伙们可以试试了
    对啦,那个数据只是接收,然后显示了,具体要怎么解析,获取端口号啥的就让小伙伴们自己来吧。。

    展开全文
  • Unity3D内部串口通信和Unity3D与WinForm程序间的串口通信。容易引发的错误、异常,以及串口正常工作的区别。解决方法和思路。

    前言

    1、有些人其实会觉得Unity3D用到的.NET是2.0的,其实不然;Unity3D有用到.NET3.5,为什么说Unity用到的是3.5呢,从一个很常用却很重要的一个命名空间说起,他就是System.Linq命名空间,这个命名空间是.NET3.5重要的一次改革和核心部分(本命名空间与该文章并没有什么很大的联系,只是提下而已)。至于为什么显示成2.0我也不是很清楚,可能只支持部分3.5吧,不过对我们来说关系并不是很大。只要支持Linq就可以了。

    2、前提工作:虚拟串口和Unity3D切换成.NET。
    2.1 虚拟串口的创建,可以从网上下载一个创建虚拟串口的软件,比如“VSPD虚拟串口”,还是挺好用的,不过因为我做Unity3D的虚拟串口工作,所以根据VSPD专门写了一个创建虚拟串口的程序(暂时不提供)。在创建虚拟串口的时候注意一个很重要的问题,就是尽量创建串口号大于10的,比如COM10、COM11甚至夸张点COM100等,为什么要这样子,后面我会介绍Unity3D打开串口时,串口号大于10时,打开串口方式与.NET打开串口的方式是不一样的。
    2.2 将Unity3D的API平台切换成.NET2.0。如何切换“Edit–>project Setting–>Player–>Other Setting –>Api Compatibility level”。在这里将“.NET2.0 Subset”切换为“.NET2.0”

    切换.NET2.0
    2.3 Unity的目标平台一定要切换为Windows平台,否则是其他平台会报错误,本人就是深有体会,针对这个问题找原因找了很久,什么百度、谷歌、论坛都查阅了,最后还是无意中自己发现解决的了。

    平台切换
    切换为Web平台时报的错误
    Web平台
    3、Unity的串口与.NET的串口对象参数有些不一样,比如在Unity3D中打开串口,SerialPort对象的属性、方法、事件等要比.NET SerialPort对象的属性、事件、方法要少一些。(图片不能显示,所以不就贴图了,只是说明下情况),甚至Unity3D的有些属性还是错误的,比如BytesToRead和BytesToWrite两个属性都是“未将对象引用值对象的实例”,但是在.NET中这两个参数默认是为0。这两个参数用于接收串口发送字节数组时,是很有用处的。
    这是Unity中串口对象里的属性
    Unity中串口对象里的属性
    这是WinForm中串口对象里的属性
    WinForm中串口对象里的属性
    4、虚拟串口的创建,不像是真实串口线那样子,它是以对来创建的,比如COM100与COM101一对……至于怎么成对完全是有那个创建虚拟串口的软件以及你输入的串口来决定的。
    设备管理器中串口号

    一、Unity3D内部串口通信

    1、内部通信思路
    1.1 打开串口
    之前在前言中说过,Unity打开串口方式不一样,因为在.NET2.0打开串口时,如果串口超过10,则必须在前面加上“\\?\”,比如我需要打开COM301,在Unity中你实际传给串口的参数必须是“”\\?\” + “COM301””。
    在命名空间中引用System.IO.Ports
    创建两个串口类对象

    private SerialPort gatewayPort, coorPort;
    //分别是网关串口和协调器串口,命名的话随自己。
        然后写一个打开串口方法
        注意:下面的网关串口和协调器串口只是我的命名而已,其实串口之间的通信。
        **打开网关串口**
    
            gatewayPort = new SerialPort("\\\\?\\" + "COM301", 9600);
            gatewayPort.ReadTimeout = 500;
            gatewayPort.Open();
            Debug.Log("网关串口打开成功");
            //用于接收协调器串口发送过来的数据
            tgateway = new Thread(ReceivePortThread2);
            tgateway.IsBackground = true;
            tgateway.Start();
        *打开协调器串口*
    
            coorPort = new SerialPort("\\\\?\\" + "COM3301", 9600);
            coorPort.ReadTimeout = 500;
            coorPort.Open();
            Debug.Log("协调器串口打开成功");
            //用于接收网关串口发送过来的数据
            tcoor = new Thread(ReceivePortThread1);
            tcoor.IsBackground = true;
            tcoor.Start();

    1.2 线程接收数据
    两个串口接收数据,并且打印出来,一般接收数据的方法常用的有两种,一种是接收字符串ReadLine()另一种接收字节Read,稍微我会将接收字节已注释的形式写出来。

    字节接收的方式,把代码放在网关接收方法里和协调器方法里,根据个人需求吧
    //byte[] buffer = new byte[1024];
     //int count = this.coorPort.Read(buffer, 0, buffer.Length);
     //if(count == 0) {
     //    continue;
     //}
    
     //byte[] bufferRead = new byte[count];
    
     //System.Array.Copy(buffer, 0, bufferRead, 0, count);
     //string strRec = ClassConvert.BytesToString(bufferRead);
     ClassConvert类是一些字节、字符串转化的方法,后面会提供

    网关接收数据方法

        private void ReceivePortThread2()
        {
            while(true) {
                Thread.Sleep(1);
                if(this.gatewayPort != null && this.gatewayPort.IsOpen) {
                    try {
                        string strRec = gatewayPort.ReadLine(); 
                        Debug.Log("网关读取数据:" + strRec);
                    }
                    catch {
                        //continue;
                    }
                }
            }
        }

    协调器接收数据方法

        private void ReceivePortThread1()
        {
            while(true) {
                Thread.Sleep(1);
                if(this.coorPort != null && this.coorPort.IsOpen) {
                    try {
                        string strRec = coorPort.ReadLine(); 
                        Debug.Log("协调器读取数据:" + strRec);
                    }
                    catch {
                        //continue;
                    }
                }
            }
        }

    1.3 发送数据
    将这下面两个方法分别加入到UI Button的事件中,具体如何加这里就不解释了。

        /// <summary>
        /// 网关
        /// </summary>
        public void OnGateWay()
        {
            this.gatewayPort.DiscardOutBuffer();
            gatewayPort.WriteLine("FF0000");
    
            //byte[] buffer = new byte[] { 0xFF, 0x00, 0x01 };
            //gatewayPort.Write(buffer, 0, buffer.Length);
        }
    
        /// <summary>
        /// 协调器
        /// </summary>
        public void OnCoor()
        {
            this.coorPort.DiscardOutBuffer();
            coorPort.WriteLine("00FFFF");
            //byte[] buffer = new byte[] { 0x00, 0xFF, 0xFE };
            //coorPort.Write(buffer, 0, buffer.Length);
        }

    2、代码
    主要类PortsTest.cs,字节字符串转化类ClassConvert.cs

    using UnityEngine;
    using System.Collections;
    using UnityEngine.UI;
    using System.IO.Ports;
    using System.Threading;
    
    public class PortsTest : MonoBehaviour {
    
        private SerialPort gatewayPort, coorPort;
    
        public Thread tgateway, tcoor;
    
        // Use this for initialization
        void Start () {
            GateWayOpen();
            CoorOpen();
        }
    
        // Update is called once per frame
        void Update () {
    
        }
    
        void GateWayOpen()
        {
            gatewayPort = new SerialPort("\\\\?\\" + "COM301", 9600);
            gatewayPort.ReadTimeout = 500;
            gatewayPort.Open();
            Debug.Log("网关串口打开成功");
    
            tgateway = new Thread(ReceivePortThread2);
            tgateway.IsBackground = true;
            tgateway.Start();
    
        }
    
        void CoorOpen()
        {
            coorPort = new SerialPort("\\\\?\\" + "COM3301", 9600);
            coorPort.ReadTimeout = 500;
            coorPort.Open();
            Debug.Log("协调器串口打开成功");
    
            tcoor = new Thread(ReceivePortThread1);
            tcoor.IsBackground = true;
            tcoor.Start();
        }
    
        /// <summary>
        /// 串口接收数据方法
        /// </summary>
        private void ReceivePortThread1()
        {
            while(true) {
                Thread.Sleep(1);
    
                if(this.coorPort != null && this.coorPort.IsOpen) {
                    try {
                        //byte[] buffer = new byte[1024];
                        //int count = this.coorPort.Read(buffer, 0, buffer.Length);
                        //if(count == 0) {
                        //    continue;
                        //}
    
                        //byte[] bufferRead = new byte[count];
    
                        //System.Array.Copy(buffer, 0, bufferRead, 0, count);
                        //string strRec = ClassConvert.BytesToString(bufferRead);
    
                        string strRec = coorPort.ReadLine();   
    
                        Debug.Log("协调器读取数据:" + strRec);
                    }
                    catch {
                        //continue;
                    }
                }
            }
        }
    
        /// <summary>
        /// 串口接收数据方法
        /// </summary>
        private void ReceivePortThread2()
        {
            while(true) {
                Thread.Sleep(1);
    
                if(this.gatewayPort != null && this.gatewayPort.IsOpen) {
                    try {
                        string strRec = gatewayPort.ReadLine();   
                        Debug.Log("网关读取数据:" + strRec);
                    }
                    catch {
                        //continue;
                    }
                }
            }
        }
    
        /// <summary>
        /// 网关
        /// </summary>
        public void OnGateWay()
        {
            this.gatewayPort.DiscardOutBuffer();
            gatewayPort.WriteLine("FF0000");
    
            //byte[] buffer = new byte[] { 0xFF, 0x00, 0x01 };
            //gatewayPort.Write(buffer, 0, buffer.Length);
        }
    
        /// <summary>
        /// 协调器
        /// </summary>
        public void OnCoor()
        {
            this.coorPort.DiscardOutBuffer();
            coorPort.WriteLine("00FFFF");
            //byte[] buffer = new byte[] { 0x00, 0xFF, 0xFE };
            //coorPort.Write(buffer, 0, buffer.Length);
        }
    }
    
    using System;
    
    public class ClassConvert
    {
        /// <summary>
        /// 字节数据转字符串
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static string BytesToString(byte[] bytes)
        {
            string result = "";
            foreach (byte b in bytes)
            {
                result = result + string.Format("{0:X2}", b);
            }
            return result;
        }
    
        /// <summary>
        /// 字节数据转字符串(带格式)
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static string BytesToStringFormat(byte[] bytes)
        {
            string result = "";
            foreach (byte b in bytes)
            {
                result = result + string.Format("{0:X2}", b) + "-";
            }
            return result.Substring(0, result.Length - 1);
        }
    
        /// <summary>
        /// 2位字符串转字节
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static byte StringToByte(string str)
        {
            try
            {
                str = System.Convert.ToInt32(str, 16).ToString();
            }
            catch (Exception err)
            {
                throw err;
            }
    
            byte result = 0;
            if (byte.TryParse(str, out result) == true)
            {
                return result;
            }
            else
            {
                throw new Exception("StringToByte error");
            }
        }
    
        /// <summary>
        /// 字符串转字节数据
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static byte[] StringToBytes(string str)
        {
            byte[] result = new byte[str.Length / 2];
            for (int i = 0; i < str.Length; i = i + 2)
            {
                result[i / 2] = StringToByte(str.Substring(i, 2));
            }
            return result;
        }
    }
    

    3、运行结果和异常解析
    运行程序后,会提示网关串口打开成功和协调器串口打开成功。
    3.1、当以字符串形式发送串口数据和接收串口数据时,会发现一个问题就是在接收串口数据时,会出现数据丢失的情况,网关串口向协调器发送”FF0000”时,协调器接收数据偶尔会接收到“F0000”甚至是为空,只有当连续发送两次时,才会成功。
    运行结果,数据出现丢失
    3.2、当以字节发送和接收串口数据时,会出现一条完整的数据会以两次打印出来。比如将“new byte[] { 0xFF, 0x00, 0x01 }”发送过去,然后打印出来的结果是第一条是FF 第二条是00 01等等情况,感觉像是随机的。
    运行结果
    3、当以字节发送,字符串形式接收时,是无法接收数据的。

    以上问题目前我也不知道是什么情况,解决思路是怎样的,发生该问题的原因可能是因为Unity对串口这块本身支持就不是很大,毕竟不是专门针对Windows平台的,如果有看到本文章的读者知道的话,请联系我的邮箱:1158078383@qq.com 或者微博:http://weibo.com/5062862016/profile?topnav=1&wvr=6&is_all=1 本人非常感谢!!

    二、Unity3D与Winform程序之间的串口通信

    在第一部分中介绍了Unity3D内部间的通信,现在测试Unity3D与Winform程序之间的串口通信。
    首先Unity3D串口程序跟第一节类似的,只不过把网关打开串口那一部分代码移植到Winform中,然后修改一下打开串口的方式即可。
    1、打开串口方式

    private SerialPort gatewayPort;
    public Thread tgateway;
    
    gatewayPort = new SerialPort("COM202", 9600);
    gatewayPort.ReadTimeout = 500;
    gatewayPort.Open();
    
    tgateway = new Thread(new ThreadStart(ReceivePortThread2));
    tgateway.IsBackground = true;
    tgateway.Start();
    
    private void ReceivePortThread2()
    {
        while(true) {
            Thread.Sleep(1);
            if(this.gatewayPort != null && this.gatewayPort.IsOpen) {
                try {
                    string strRec = gatewayPort.ReadLine();  
                    MessageBox.Show(strRec);
                }
                catch {
                }
            }
        }
    }

    以上就是核心代码。
    2、遇到的问题
    发送字符串和接收字符串遇到以下发生过的问题
    2.1 winform程序发送数据成功了,但是Unity接收不到
    2.2 Unity往Winform程序总发送数据时,是没有问题的。而Unity却接收不到。
    Winform程序接收到了Unity串口发送过来的数据
    发送字节和接收字节遇到以下发生过的问题
    2.3 WinForm程序发送数据成功了,但是Unity接收到的数据存在问题,数据不符或数据中断,要想解决这个问题有两种方法:
    第一可能是Unity官方的错误,如果能做成跟.NET串口通信一致的话,那么这个问题很好解决。不过这个问题不够现实,因为Unity本身就是为游戏而开发的。
    第二那就自己去解决了,看到Unity接收到的数据存在数据不符,还有数据断层,只能根据自身的要求,然后去测试,添加校验位,根据首校验位和末校验位来截取你想要的字节。只有这样子你才可能接收到正常的串口数据。但是这样子也存在很多的局限性!!!

    2.4 Unity往WinForm程序中发送的数据时,是没有问题的。
    Unity接收到的数据和WinForm程序接收到的数据
    WinForm 接收数据关键代码:

    if(gatewayPort.BytesToRead > 0) {
         byte[] bufferRead = new byte[this.gatewayPort.BytesToRead];
         this.gatewayPort.Read(bufferRead, 0, bufferRead.Length);
         string strRec = ClassConvert.BytesToString(bufferRead);
    }

    WinForm发送数据关键代码:

    gatewayPort.DiscardInBuffer();
    byte[] buffer = new byte[] { 0xFF, 0x00, 0x01 };
    gatewayPort.Write(buffer, 0, buffer.Length);

    Unity的接收数据关键代码和发送数据关键代码已在第一节都贴出来了。

    展开全文
  • 串口助手上接收到的数据格式为 FC 02 00 00 , 02 表示有两台设备连接, 后面的两个 00 表示各自的速度 成员变量 ``` public int ClientCount = 2; //设备数量 public int[] High2Arr; //高位数组 public ...
  • Unity3D串口通信,同步读取,持续写入,串口参数通过本地文件配置。

    MGS-SerialPort

    概述

    Unity3D与串口通信,同步读取,持续写入,串口参数通过本地文件配置。

    版本

    • Unity3D 5.4.1f1。
    • .NET 2.0。

    问题

    1. Unity3D目前不能正常在Update,FixedUpdate等事件函数中直接读取串口数据,运行程序卡顿。
    2. Unity3D目前没有实现“SerialPort.ReceivedBytesThreshold”属性设置,抛出没有实现异常。
    3. Unity3D目前不能正常触发“SerialPort.DataReceived”事件,无异常抛出,无响应。
    4. Unity3D目前不能正常读取“SerialPort.BytesToRead”属性,运行程序卡死。
    5. Unity3D目前不能有效执行“SerialPort.DiscardInBuffer”方法,无异常抛出,输入缓冲区没
      能清空。
    6. Unity3D目前不能有效执行“SerialPort.DiscardOutBuffer”方法,无异常抛出,输出缓冲区没
      能清空。
    7. 上位机与下位机收发周期不一致(除特殊情况外可协调一致),每次从缓冲区读取到的数据基本
      不是一个完整的数据帧(单次接收/发送的数据),接收周期小于发送周期时,每次读取到的字
      节数小于1个数据帧长度;接收周期大于发送周期时,每次读取到的字节数大于1个数据帧长度。
    8. 即使上位机与下位机收发周期一致,因收发时刻差异,每次从缓冲区读取到的数据并非都是一个
      完整的数据帧,数据或长或短。

    方案

    参数配置

    • 串口参数按行写入到本地文本文件,便于调试,维护时修改适配。

    持续读写

    • 使用线程按照读取周期持续从串口读取数据。
    • 使用线程按照写入周期持续向串口写入数据。

    数据同步

    协议

    • 商定收发周期尽量一致,不一致也无妨。
    • 商定收发协议,数据帧长度固定,数据帧的第一个字节作为收发头部标记(ReadHead/WiteHead),
      数据帧的最后一个字节作为收发尾部标记(ReadTail/WiteTail),剩余字节数作为收发数据计
      数(ReadCount/WriteCount)。

    读取

    1. 读取整个缓冲区Buffer,并获取读取到的字节数Count;事实上,如果程序运行内存吃紧且收发
      周期基本一致,那么单次可以只从缓冲区读取1个数据帧长度(ReadCount+2)的字节以节约内
      存开销,读者可根据自己的需求自行修改。
    2. 如果Count不超过2个数据帧则数据没有延迟,直接将读取到的字节数据(Buffer的前Count个字节)
      添加到一个ReadBuffer列表;否则数据有延迟冗余,将读取到的字节数据(Buffer的前Count个字节)
      的后2个数据帧长度的字节数据添加到ReadBuffer列表;因为正常情况下,2个数据帧长度的连
      续字节数据必然包含一个完整的数据帧。继续。
    3. 检查ReadBuffer的长度,如果小于1个数据帧长度则返回步骤1;如果大于或等于1个数据帧长度
      (有可能包含一个完整的数据帧),继续。
    4. 检查ReadBuffer,如果第一个字节不等于ReadHead标记,则删除这个无效字节,返回步骤3;如
      果第一个字节等于ReadHead标记,则检查第1个数据帧长度位置的字节,如果等于ReadTail标记
      则找到一个完整的数据帧,将ReadBuffer前1个数据帧长度的字节存入ReadBytes,至此,缓冲
      区中由串口发来的最近一个完整数据帧已读取到;否则数据无效;现在ReadBuffer的前1个数据
      帧长度的字节已经检查过,将其从ReadBuffer中删除,返回步骤3。

    写入

    1. 检查WriteBytes,长度不等于WriteCount则返回(避免WriteBytes被误操作重新初始化为其他长
      度的数组时,向串口写入错误的字节数据);如果长度等于WriteCount,继续。
    2. 在WriteBytes前面添加WiteHead标记,后面添加WriteTail标记,将其写入串口;返回步骤1。

    实现

    1. SerialPortConfig.cs 结构体存储串口参数配置。
    2. SerialPortConfigurer.cs 串口参数配置写入本地文件,从文件读取配置。
    3. SerialPortController.cs 串口同步读取,持续写入。

    源码

    展开全文
  • Unity 读取串口数据

    2018-10-22 14:21:04
    直接用即可,接收到信号会卡顿一下 放在线程中即可。 波特率 ,看一下你的硬件中的设置 com端口看一下你的设备管理中的串口即可。 有问题加我qq 791719266 public string portname = &amp;amp;quot...
  • public class SerialCommunication : MonoBehaviour {  public GUIText gui;  public string portName = "COM2";  public int baudRate = 9600;... public Parity parity = Parity.None;... public
  • 一、c#实现串口通信程序的开发 C#串口介绍以及简单串口通信程序设计实现 简单的串口通信工具,基于C#应用程序WinFrom实现 串口介绍  串行接口简称串口,也称串行通信接口或串行通讯接口(通常指COM...
  • 使用过一些网上一些大神的代码后,或多或少都...一次性读取完整串口数据。 using System.Collections; using System.Collections.Generic; using UnityEngine; using System.IO.Ports; using System.Threading; us...
  • 串口通信发送数据时需要将数据转换为十六进制内容 using UnityEngine; using System; using System.IO.Ports; public class spSend : MonoBehaviour { public SerialPort sp; //串口名字 static public byte[]...
  • Unity3D开发之串口通信

    2019-12-04 17:07:55
    unity读取串口数据代码如下: public class GetIdTest : MonoBehaviour { private SerialPort sp; private Thread recvThread;//线程 void Start() { sp = new SerialPort("COM3", 9600, Parity.Non...
  • unity中用自写代码,在虚拟串口间进行传输数据是可以的,但是用RS485转usb设备链接到串口 ,会出现以下情况 1,端口可以打开但是没有检测到载波sp.CDHolding返回的false,设备数据传输LED灯不亮 2,用设备厂家给...
  • 这是我网上查阅了大量资料、文档后自己修改、总结做出来的,网上大部分都是debug形式显示数据,然后我做的是显示到text中去的,功能就是接收单片机发送过来的数据,并显示到unity3d里面,里面包含有两种显示形式,一...
  • Unity3D串口处理

    2019-07-23 15:00:31
    最近公司用U3D开发一个应用...遇到这个问题很是棘手啊,后来在网上搜了一下,发现这个问题确实存在,解决的方法是开启两个线程,一个用来接收数据,一个用来处理数据。将两个线程分别放在FixedUpdate里面调用,这样...
  • unity3d串口的使用

    2019-07-22 21:02:02
    (经过试验,unity无法用串口自带的事件进行数据读取); 看完以后,个人感觉比较麻烦,所以就用了下面的方式; PS:也可以改成用IEnumerator 或者Invoke来写 1 using UnityEngine; 2 using Sys...
  • Unity3D的API平台切换成.NET2.0,切换方法: “Edit–>project Setting–>Player–>Other Setting –>Api Compatibility level”。在这里将“.NET2.0 Subset”切换为“.NET4.X”(.NET2.0也可以)。以...
1 2 3 4 5 6
收藏数 102
精华内容 40