IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Unity 串口接收的报文不完整?处理方式在这 -> 正文阅读

[游戏开发]Unity 串口接收的报文不完整?处理方式在这

串口通讯

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. 对偶然情况,比如发送端是分两次发送的正确数据无法处理,这样的情况这段代码无法排除。

结束

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-10-28 12:39:48  更:2021-10-28 12:40:17 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/20 6:56:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码