C#串口和Unity实现串口通讯

1 篇文章 0 订阅

一:.Net下串口通讯

.Net平台下,微软已经把串口部分封装地非常好了,大多出场景下我们都直接用。

其中在接收串口数据的时候比较常见的有三种实现方式。

1.用串口封装的DataReceived事件,当串口接收到数据时,会触发这个回调函数,在回调函数中读出串口中的数据。

如下回调

   private void _Serial_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            SerialPort sp = sender as SerialPort;
            if (sp == null) return;
            int tmpBytesCount = sp.BytesToRead;
            byte[] tmpData = new byte[tmpBytesCount];
            int tmpRealDataCount = sp.Read(tmpData, 0, tmpBytesCount);
            byte[] tmpValidData = null;
            if (tmpRealDataCount == tmpBytesCount)
            {
                tmpValidData = tmpData;
            }
            else
            {
                tmpValidData = new byte[tmpRealDataCount];
                Array.Copy(tmpData, 0, tmpValidData, 0, tmpRealDataCount);
            }

            logClass.WriteLog(LogFile.appData, string.Format("发送:{0}", BytesToStr(tmpValidData)));

            if (DataReceiveEvent != null)
                DataReceiveEvent(tmpValidData);

        }

2.写死循环,不停地在串口中读取数据,如下代码

        private void ReadDataPro()
        {
            int readCount = 0;
            byte[] data;
            byte[] buffer = new byte[2048];

            Stream baseStream = _Serial.BaseStream;
            baseStream.ReadByte();

            while (ReadDataRunFlag)
            {
                if (_Serial == null || !_Serial.IsOpen) continue;

                readCount = _Serial.Read(buffer, 0, buffer.Length);
                if (readCount > 0)
                {
                    data = new byte[readCount];
                    Array.Copy(buffer, 0, data, 0, data.Length);
                    if (DataReceiveEvent != null)
                        DataReceiveEvent(data);
                }
                else
                {
                    Thread.Sleep(1);
                }
            }
        }

3.拿到串口基础流,对流进行操作。对流进行操作时比较灵活,所有Steam的方法都可以实用,用这种方式可是实现更复杂的功能。

        private void ReadDataBasePro()
        {
            int readCount = 0;
            byte[] data;
            byte[] buffer = new byte[2048];

            Stream baseStream = _Serial.BaseStream;

            while (ReadDataRunFlag)
            {
                if (_Serial == null || !_Serial.IsOpen) continue;

                readCount = baseStream.Read(buffer, 0, buffer.Length);
                if (readCount > 0)
                {
                    data = new byte[readCount];
                    Array.Copy(buffer, 0, data, 0, data.Length);
                    if (DataReceiveEvent != null)
                        DataReceiveEvent(data);
                }
                else
                {
                    Thread.Sleep(1);
                }
            }
        }

二.unity中串口通讯

说明:小弟我是做C#的,unity 只是了解那么一丢丢。但是最近用到unity中的串口通讯,掉进了一些坑,在这里拿出来分享,以免用到相关知识的朋友走弯路。

1.经测试,DataReceived事件在unity中不触发。在unity中如果用DataReceived事件触发接收数据逻辑,会发现串口代码不报错,但是只能发送数据,不能接收数据,其实就是这个里在作祟,事件不触发,一直没有执行接收数据的代码。

2.BytesToRead方法会报错。所以在unity中不要使用这个方法来判断当前串口缓冲中有多少可用数据。而是直接使用                    readCount = _Serial.Read(buffer, 0, buffer.Length);这个方法,通过返回值来判断。

3.当使用全双工通讯并且收发时间密集时,接收偶尔会丢失首个字节,这里需要把unity环境改外4.x

三.总结

通常把功能性相关类直接从.Net C#项目中移植到unity中,修改编译错误后,会遇到很多莫名其妙的运行中问题。

这是为什么呢?

今天没事看了一下,.net平台和unity框架 下的.net平台,他们所用的基础类库是不一样的。

比如说Unity 的system类库在我电脑上路径为D:\Program Files\Unity\Editor\Data\MonoBleedingEdge\lib\mono\4.7.1-api\System.dll

而标准.net下system类库为C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.dll

所以,虽然表面上类、方法、属性都一样,但是可能实现不一样,会导致各种运行中问题。

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值