485通信偶尔read接收不到数据

485通信为什么偶尔接收不到数据,错误数据非常少,也用了串口助手,代码用在422也没什么问题,硬件问题可能性也不大
res是read读到的数据大小

img

没有代码,不知道你怎么读的
如果是某些人教的 sleep读取,读的0很正常。因为这个只是轮询,有没有数据,有多少数据靠运气
如果是官方的事件读取,读的0也很正常
先看官方说明:
https://learn.microsoft.com/zh-cn/dotnet/api/system.io.ports.serialport.datareceived?view=dotnet-plat-ext-7.0#system-io-ports-serialport-datareceived

看下面的注解

数据事件可能由枚举中的任何 SerialData 项引起。 由于操作系统确定是否引发此事件,因此不会报告所有奇偶校验错误。
DataReceived如果收到 Eof 字符,则也会引发 事件,而不考虑内部输入缓冲区中的字节数和 属性的值ReceivedBytesThreshold。
PinChanged、 DataReceived和 ErrorReceived 事件可能会不按顺序调用,并且基础流报告错误和执行事件处理程序之间可能会有轻微的延迟。 一次只能执行一个事件处理程序。
DataReceived不保证每个接收字节都会引发事件。 BytesToRead使用 属性确定要读取缓冲区中剩余的数据量。
DataReceived从 对象接收数据时,会在辅助线程上引发 该SerialPort事件。 由于此事件是在辅助线程而不是main线程上引发的,因此尝试修改main线程中的某些元素(例如 UI 元素)可能会引发线程异常。 如果需要修改 main Form 或 Control中的元素,请使用 发布更改请求,Invoke这将在正确的线程上执行工作

官方已经告诉你,数据先入缓冲区
1.依靠ReceivedBytesThreshold数字触发。默认是1,也就是他其实并不管你是不是2212 个字节,默认只要大于1就会触发


2.上面所有资料都说明,如果碰到EOF也会触发。所以他会偶发出现一些不按规律触发的事件

同时我个人也得说,触发只是触发。他不代表什么。系统仅仅只是告诉你“缓冲区有数据,需要你读取“,并不是告诉你缓冲区就一定有你指定大小的数据

比如驱动由DMA方式直接写入缓冲202字节,触发默认规则字节数大于1规定,于是给你一个事件。
然后你收到事件,开始读取。此刻串口驱动其实并没有等你,他还在继续写入缓冲,所以你可能读取到300字节

所以真实的开发中,我们并不靠数据个数去判定对不对,我们靠双方的协议去判定对不对