C#串口数据接收问题

兵书狂剑 2015-01-09 10:33:24
我用c#编写了一个串口数据接收软件,接收的数据为16进制的6个字符,每秒一次,我软件接受到的数据中大部分是对的,但会有一部分错误,不知道什么原因,发送的数据肯定没有问题,用其他串口调试助手试过,不知道程序是哪的问题,求大神帮我看看,谢谢!

private void comm_DataReceived_1(object sender, SerialDataReceivedEventArgs e)
{
yanshi++;
if (yanshi < 10) return; //仪器的初始化
Data_Receive.Clear();
Thread.Sleep(100); //读取速度太慢,加Sleep延长读取时间, 不可缺少
byte[] buf = new byte[6]; //声明一个临时数组存储当前来的串口数据
received_count += 1; //增加接收计数
comm.Read(buf, 0, 6); //读取缓冲数据
comm.DiscardInBuffer(); //清空缓存,避免下次的数据相互干扰
}

上面是代码,请大神帮我看看,buf中的数据会不定时出现几个与发送不同的数据
...全文
390 16 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
本拉灯 2015-01-13
  • 打赏
  • 举报
回复
引用 14 楼 daizhonghua22 的回复:
[quote=引用 13 楼 wyd1520 的回复:] 好久没来了,看到这个楼主写的那个接收方法明显有问题,comm.DiscardInBuffer(); 特别是用上了这个。。。 串口发送过来的数据,有时还在缓存区,如果没达到一定的长度是不会触发DataRevive事件 此时你把他清空了,就造成你上面说的200个数据出错。那是因为它也像TCPIP通信一样,在接收的缓存区 粘包。串口数据接收到的数据,下位机有时发送6个字符过来。你的上位机在DataRecive时不一定就是6个字符,有可能是分成两次接收,先接收到4个字符,第二次是2个字符。 这是时有发生的,也就是发生了你上面的问题了,你做这个,应写一个接收字节缓冲区,专门接收字节,也不用Sleep() 看一下这个吧,http://blog.csdn.net/wyd1520/article/details/23822313 这个也是为论坛另一网友跟你提的一样的问题写的。 这是当时他提的原贴子 http://bbs.csdn.net/topics/390316188
牛X,还想问另一个问题,我定义了一个鼠标滚轮的事件,但我滚轮动一下,这个事件却执行好[/quote]
引用 14 楼 daizhonghua22 的回复:
[quote=引用 13 楼 wyd1520 的回复:] 好久没来了,看到这个楼主写的那个接收方法明显有问题,comm.DiscardInBuffer(); 特别是用上了这个。。。 串口发送过来的数据,有时还在缓存区,如果没达到一定的长度是不会触发DataRevive事件 此时你把他清空了,就造成你上面说的200个数据出错。那是因为它也像TCPIP通信一样,在接收的缓存区 粘包。串口数据接收到的数据,下位机有时发送6个字符过来。你的上位机在DataRecive时不一定就是6个字符,有可能是分成两次接收,先接收到4个字符,第二次是2个字符。 这是时有发生的,也就是发生了你上面的问题了,你做这个,应写一个接收字节缓冲区,专门接收字节,也不用Sleep() 看一下这个吧,http://blog.csdn.net/wyd1520/article/details/23822313 这个也是为论坛另一网友跟你提的一样的问题写的。 这是当时他提的原贴子 http://bbs.csdn.net/topics/390316188
牛X,还想问另一个问题,我定义了一个鼠标滚轮的事件,但我滚轮动一下,这个事件却执行好[/quote] 一个问题开一贴。。。
luobing261314 2015-01-13
  • 打赏
  • 举报
回复
串口本来也并不保证数据一定能够正常接收到 它本身是利用电路的高低电平切换来实现通信的 TCP协议底层封装好了校验的方法,如果数据出错,数据包会被丢弃 而串口通信是一个字节一个字节发送,一个字节一个字节接收,并没有"包"的概念 需要你自己制定协议来校验什么样算一组数据,同一组数据通过什么来检测它是否完整,是否有错误 参考SUM校验,CRC校验,MODBUS RTU协议
兵书狂剑 2015-01-13
  • 打赏
  • 举报
回复
引用 13 楼 wyd1520 的回复:
好久没来了,看到这个楼主写的那个接收方法明显有问题,comm.DiscardInBuffer(); 特别是用上了这个。。。 串口发送过来的数据,有时还在缓存区,如果没达到一定的长度是不会触发DataRevive事件 此时你把他清空了,就造成你上面说的200个数据出错。那是因为它也像TCPIP通信一样,在接收的缓存区 粘包。串口数据接收到的数据,下位机有时发送6个字符过来。你的上位机在DataRecive时不一定就是6个字符,有可能是分成两次接收,先接收到4个字符,第二次是2个字符。 这是时有发生的,也就是发生了你上面的问题了,你做这个,应写一个接收字节缓冲区,专门接收字节,也不用Sleep() 看一下这个吧,http://blog.csdn.net/wyd1520/article/details/23822313 这个也是为论坛另一网友跟你提的一样的问题写的。 这是当时他提的原贴子 http://bbs.csdn.net/topics/390316188
牛X,还想问另一个问题,我定义了一个鼠标滚轮的事件,但我滚轮动一下,这个事件却执行好
本拉灯 2015-01-10
  • 打赏
  • 举报
回复
好久没来了,看到这个楼主写的那个接收方法明显有问题,comm.DiscardInBuffer(); 特别是用上了这个。。。 串口发送过来的数据,有时还在缓存区,如果没达到一定的长度是不会触发DataRevive事件 此时你把他清空了,就造成你上面说的200个数据出错。那是因为它也像TCPIP通信一样,在接收的缓存区 粘包。串口数据接收到的数据,下位机有时发送6个字符过来。你的上位机在DataRecive时不一定就是6个字符,有可能是分成两次接收,先接收到4个字符,第二次是2个字符。 这是时有发生的,也就是发生了你上面的问题了,你做这个,应写一个接收字节缓冲区,专门接收字节,也不用Sleep() 看一下这个吧,http://blog.csdn.net/wyd1520/article/details/23822313 这个也是为论坛另一网友跟你提的一样的问题写的。 这是当时他提的原贴子 http://bbs.csdn.net/topics/390316188
於黾 2015-01-09
  • 打赏
  • 举报
回复
串口本来也并不保证数据一定能够正常接收到 它本身是利用电路的高低电平切换来实现通信的 TCP协议底层封装好了校验的方法,如果数据出错,数据包会被丢弃 而串口通信是一个字节一个字节发送,一个字节一个字节接收,并没有"包"的概念 需要你自己制定协议来校验什么样算一组数据,同一组数据通过什么来检测它是否完整,是否有错误 参考SUM校验,CRC校验,MODBUS RTU协议
bdmh 2015-01-09
  • 打赏
  • 举报
回复
我们更不知道了,你和上游通信,先制定好协议,然后调整串口参数,把你接收到的内容跟上游作对比,看看是接收问题还是发送问题
兵书狂剑 2015-01-09
  • 打赏
  • 举报
回复
引用 4 楼 Z65443344 的回复:
[quote=引用 3 楼 daizhonghua22 的回复:] 我用串口调试助手接收数据都没有问题,应该不是发送的问题,应该是接收的问题,跟协议应该没有关系,请大家再帮我看看
你用串口调试助手跟踪了多长时间发现没有问题? 你的程序中不定时发生问题又是多长时间? 不要以为串口调试助手1分钟没有问题,再过5小时就都不会有问题[/quote] 我用串口调试助手测了8个小时左右都没问题,但用自己的软件就会出错,但也测了7、8个小时,每秒读一次的话,总共有2、3万组数,大概有200个数据出错,出错有时是连着2、3个,有时间断,出错也没有规律,发送应该没问题,还有我comm控件的ReceivedBytesThreshol写的是6(为了保证读数完整性,默认为1的),可不可能是这个原因?
兵书狂剑 2015-01-09
  • 打赏
  • 举报
回复
引用 4 楼 Z65443344 的回复:
[quote=引用 3 楼 daizhonghua22 的回复:] 我用串口调试助手接收数据都没有问题,应该不是发送的问题,应该是接收的问题,跟协议应该没有关系,请大家再帮我看看
你用串口调试助手跟踪了多长时间发现没有问题? 你的程序中不定时发生问题又是多长时间? 不要以为串口调试助手1分钟没有问题,再过5小时就都不会有问题[/quote] 我用串口调试助手测了8个小时左右都没问题,但用自己的软件就会出错,但也测了7、8个小时,每秒读一次的话,总共有2、3万组数,大概有200个数据出错,出错有时是连着2、3个,有时间断,出错也没有规律,发送应该没问题,还有我comm控件的ReceivedBytesThreshol写的是6(为了保证读数完整性,默认为1的),可不可能是这个原因?
兵书狂剑 2015-01-09
  • 打赏
  • 举报
回复
引用 4 楼 Z65443344 的回复:
[quote=引用 3 楼 daizhonghua22 的回复:] 我用串口调试助手接收数据都没有问题,应该不是发送的问题,应该是接收的问题,跟协议应该没有关系,请大家再帮我看看
你用串口调试助手跟踪了多长时间发现没有问题? 你的程序中不定时发生问题又是多长时间? 不要以为串口调试助手1分钟没有问题,再过5小时就都不会有问题[/quote] 我用串口助手跟踪了8个小时,没有一个数据错误的,换自己的软件,过了一段时间就有几个错误,错误有时是连着的,有时不是,错误时间也没有规律,还有串口缓存中的数据是怎么存的,每次都会自动清空吗,还有我的串口控件comm的属性ReceivedBytesThreshol设置的是6(为了获取完整数据),跟这个有关系吗?
於黾 2015-01-09
  • 打赏
  • 举报
回复
比如串口线附近有个大电机启动了,一个强电磁干扰很可能使你的数据全部变成0xff
於黾 2015-01-09
  • 打赏
  • 举报
回复
引用 7 楼 lincolnandlinda 的回复:
comm.DiscardInBuffer(); //清空缓存,避免下次的数据相互干扰 为什么要Discard,把这行去掉试试
如果楼主说收到的数据丢失了几个字节,可能是由于这个原因,否则跟它没什么关系,清不清里面也没有数据的 如果是数据错误,这个跟串口通信本身的硬件机制有关系,本来就很可能造成数据错误
lincolnandlinda 2015-01-09
  • 打赏
  • 举报
回复
comm.DiscardInBuffer(); //清空缓存,避免下次的数据相互干扰 为什么要Discard,把这行去掉试试
於黾 2015-01-09
  • 打赏
  • 举报
回复
引用 5 楼 Saleayas 的回复:
我好奇怪哦,读取的时候,很多人都是尽快的读取数据,还没有看到需要延时读取的。
延时读取逻辑简单,不用考虑分包接包的问题 正规的做法应该是接收到数据后判断是否完整,不完整继续读取,然后自己拼接
Saleayas 2015-01-09
  • 打赏
  • 举报
回复
我好奇怪哦,读取的时候,很多人都是尽快的读取数据,还没有看到需要延时读取的。
於黾 2015-01-09
  • 打赏
  • 举报
回复
引用 3 楼 daizhonghua22 的回复:
我用串口调试助手接收数据都没有问题,应该不是发送的问题,应该是接收的问题,跟协议应该没有关系,请大家再帮我看看
你用串口调试助手跟踪了多长时间发现没有问题? 你的程序中不定时发生问题又是多长时间? 不要以为串口调试助手1分钟没有问题,再过5小时就都不会有问题
兵书狂剑 2015-01-09
  • 打赏
  • 举报
回复
我用串口调试助手接收数据都没有问题,应该不是发送的问题,应该是接收的问题,跟协议应该没有关系,请大家再帮我看看

111,098

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧