Unity 串口接收的报文不完整?处理方式在这

5 篇文章 0 订阅

串口通讯

Unity 中的串口通讯和C#的处理方式基本一致,

  1. Serial.Read(); 可以读取缓存区中的十六进制数
  2. Serial.ReadLine();可以以字符串的方式读取

Read()函数的处理

但是Read()函数有一个大坑,就是他不是一次性全读取,而是将缓存区中的数据分多次(一般是两次)读取,这个情况的产生不是因为对方以两次发送过来,而是一次发送过来会放在缓存区,通过Read()函数将缓存区的数据读多次,也就是这个函数会执行多次。
这样就导致了我们要是直接在Read()下面直接进行数据处理,会将第一次的未完成数据进行处理,这样处理结果显然是错误的。、

解决问题的过程

我在遇到问题后查找的资料基本倾向于规定一个指定的接收长度,在未完成长度时继续读,直到读满长度后开始对数据进行处理。
但是我这边需要实现的功能是对三种不同长度的报文进行分类处理,这样的情况显然不对。所以只能是规定三种长度

对Read()函数的应用

所以我对串口接收数据的入口进行了一点点更改,Serial.BytesToRead函数是去直接获取缓存区的数据位数,可以通过检查缓存区的数据,进行下一步操作来确保将缓存区的数据读完。

// sp为串口

    	int index = 0;                    //用于记录此时的数据次序
        int ReadToBytes = 0;              //记录长度
        byte[] readBuffer = new byte[20]; //接收数组初始化
 while (true)
        {
            if (sp != null && sp.IsOpen)
            {
                try
                {
                    int n = sp.BytesToRead;
                    if (n > 0)
                    {
                        readBuffer = new byte[sp.BytesToRead + 1];
                        ReadToBytes = sp.Read(readBuffer, 0, n);

                        if ((n == 7) || (n == 9) || (n == 13))    //是否符合接收长度
                        {
                            index = 0;

                            for (int i = 0; i < n; i++)
                            {
                                if (index >= n) index = n - 1;		 //理论上不应该会进入此判断,但是由于传输的误码,导致数据的丢失,使得标志位与数据个数出错
                                data[index] = readBuffer[i];         //将数据存入数据处理数组data中
                                index++;
                            }

                        }
               		}
               		DataProcessingFunction(index, data);  //数据处理
				}
				catch (Exception ex)
                {
                    if (ex.GetType() != typeof(ThreadAbortException))
                    {

                    }
                }
			}
			Thread.Sleep(100);
		}

这段代码实际上只是对入口进行了略微处理,在开始时新建一个接收线程,在每次接收完让这个线程休眠一段时间可以确保数据不会冲突。

弊端

这样的弊端也是有的,

  1. 干扰数据也是符合这几位的话也是会键入循环,不过可以加个校验,就可以不被处理直接忽略。
  2. 对偶然情况,比如发送端是分两次发送的正确数据无法处理,这样的情况这段代码无法排除。

结束

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Unity中可以通过串口接收数据。首先,需要在Unity的脚本中引入System.IO.Ports库,该库提供了使用串口的相关功能。 首先,在脚本中定义一个SerialPort对象,用于与串口进行通信。可以通过指定串口的名称、波特率、数据位、校验位等参数来配置串口。 接下来,在需要接收数据的地方,使用SerialPort对象的ReadLine()方法读取串口接收到的数据。该方法会一直等待串口有数据可读并读取一行数据。 读取到的数据可以在Unity中进一步处理或展示,例如可以将数据显示在UI界面上、做数据分析或进行其他操作。 需要注意的是,在使用完毕后,要及时关闭串口,以免占用系统资源。可以使用SerialPort对象的Close()方法来关闭串口连接。 总结起来,Unity中通过引入System.IO.Ports库,配置和打开串口后,可以通过SerialPort对象的ReadLine()方法来接收来自串口的数据,并进行进一步的处理和展示。使用完毕后,要记得关闭串口连接。 ### 回答2: 在Unity中实现串口接收数据的方法如下: 1. 首先,在Unity中创建一个脚本,用于管理串口数据的接收和处理。 2. 在脚本中使用SerialPort类来打开串口。你需要指定串口名称和波特率。 3. 接下来,你可以使用SerialPort类的Read方法来读取串口数据。你可以选择在Update函数中不断读取数据,或者通过协程来进行读取。 4. 读取到的串口数据将以字节数组的形式返回。你可以使用Encoding类来将字节数组转换为字符串,以便进一步处理。 5. 在处理串口数据前,你可能需要对其进行一些预处理,例如去除空格或特殊字符,或者将数据转换为特定的格式。 6. 处理完数据后,你可以根据需要在Unity场景中进行相关操作,例如更新游戏对象的位置、状态等等。 7. 当你不再需要使用串口时,记得调用SerialPort类的Close方法来关闭串口连接,以释放资源。 需要注意的是,在使用串口接收数据时,要确保你的设备与电脑正确连接,并且串口名称和波特率设置正确。在测试时,可以使用调试工具或者其他串口通信软件模拟发送数据,以验证接收功能是否正常工作。此外,尽量避免在主线程中进行长时间的串口读取操作,以免影响游戏的帧率和响应性能。可以考虑使用线程或协程来实现串口数据的异步读取和处理。 ### 回答3: Unity是一种跨平台的游戏开发引擎,可以在不同操作系统进行开发。在Unity中,通过使用SerialPort类可以实现串口通信,并实现数据的接收。 首先,需要在Unity中引入System.IO命名空间,以便使用SerialPort类。接下来,创建一个SerialPort对象,指定串口号、波特率、数据位、停止位等参数。然后,调用SerialPort类的Open()方法打开串口。 为了接收数据,可以使用Unity的Update()函数来实现数据的实时接收。在Update()函数中,可以使用SerialPort类的ReadLine()方法或Read()方法来接收串口数据。ReadLine()方法会一次性读取一行数据,而Read()方法会读取指定长度的数据。 接收到的数据可以存储在一个字符串或字节数组中,然后可以对数据进行解析和处理。例如,可以将接收到的字符串转换成数字、判断特定的数据或命令等。 在整个过程中,需要注意处理好异常情况。在数据接收完毕后,务必调用SerialPort类的Close()方法来关闭串口。同时,在程序退出时,需要保证释放SerialPort对象的资源。 总之,Unity可以方便地实现串口数据的接收,通过使用SerialPort类,指定串口参数并调用相关函数即可。接收到的数据可以在Unity中进一步处理和应用。同时,需要注意异常处理和资源释放,以确保程序的正常运行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

辰似五味

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值