使用C# serialport类,用委托进行串口数据接收,接收时需要数据处理和绘图,怎样同步数据防止丢失?
C#串口每2s定时接收数据,接收数据同时进行数据处理和绘图显示,接收数据长度固定为47个字节。正常情况下接收和显示没有问题,但是出错时发现数据没有同步上,即接收的数据头部...
C#串口每2s定时接收数据,接收数据同时进行数据处理和绘图显示,接收数据长度固定为47个字节。正常情况下接收和显示没有问题,但是出错时发现数据没有同步上,即接收的数据头部不是我想要的头部,所以里边的数据结构错位了,我初步判断是上位机处理速度没有跟上(因为有绘图和算法处理),而发送端可能过快,导致了数据的丢失。请问如何改善程序?
1、我使用的是c# 的serialport类,串口数据采用中断接收,每隔47个字节产生一个中断。接收后判断头部是否与是我预先设定的。然后进行处理,如果不是则丢弃。我的程序到出错时头部就找不到了。
2、我接收使用的是委托,使用的是this.Invoke(p,recievebuf);这个来处理。
3、之前还出现过timeout exception是串口的后来加上了try catch 语句给忽略了。 展开
1、我使用的是c# 的serialport类,串口数据采用中断接收,每隔47个字节产生一个中断。接收后判断头部是否与是我预先设定的。然后进行处理,如果不是则丢弃。我的程序到出错时头部就找不到了。
2、我接收使用的是委托,使用的是this.Invoke(p,recievebuf);这个来处理。
3、之前还出现过timeout exception是串口的后来加上了try catch 语句给忽略了。 展开
2个回答
展开全部
只说原理
你的需求实际上是一个简单的生产者和消者费的关系,需要用到多线程,你可以按这个关键字去查一下 生产者 消费者 c#
1、串口数据不能固定长度的,即使你下位机发出47字节,你收到数据时也可能会分成多个部分接收。
2、serialport有数据到达时的触发事件,不需要你去定时接收数据,头部判断这个你已经弄错了,一般的方法是上位机收到数据触发时,将收到的数据放入一个缓冲区(可以是List<byte>也可以是Queue<byte>或者string也行),这个就是生产者。
3、在独立的消费者线程里,从缓冲区头上开始检查是否有指定起始和和结束的指令,比如说总是AB xx xx xx xx FF,如果有这种数据,处理数据比如绘图等等,然后把处理完的数据从缓冲区内删除。剩下的数据继续留在缓冲区。
举个例子,比如指令总长4字节,以AB开始,FF结束,那假定收到的是
AB D0 C0 FF AB A5
送入消费者之后,就是处理掉AB D0 C0 FF,剩下的AB A5将继续保留,等待下一次接收数据
你的需求实际上是一个简单的生产者和消者费的关系,需要用到多线程,你可以按这个关键字去查一下 生产者 消费者 c#
1、串口数据不能固定长度的,即使你下位机发出47字节,你收到数据时也可能会分成多个部分接收。
2、serialport有数据到达时的触发事件,不需要你去定时接收数据,头部判断这个你已经弄错了,一般的方法是上位机收到数据触发时,将收到的数据放入一个缓冲区(可以是List<byte>也可以是Queue<byte>或者string也行),这个就是生产者。
3、在独立的消费者线程里,从缓冲区头上开始检查是否有指定起始和和结束的指令,比如说总是AB xx xx xx xx FF,如果有这种数据,处理数据比如绘图等等,然后把处理完的数据从缓冲区内删除。剩下的数据继续留在缓冲区。
举个例子,比如指令总长4字节,以AB开始,FF结束,那假定收到的是
AB D0 C0 FF AB A5
送入消费者之后,就是处理掉AB D0 C0 FF,剩下的AB A5将继续保留,等待下一次接收数据
追问
那个serialport 的RecieveBytesThreshold属性是47,是可以将串口设置成固定数据接收的。我的程序可以这样固定数据字节接收,但是运行一阵子后会错位。因此应该是没有搞缓冲区用线程同步的问题,总之谢谢你了。
追答
不能用RecieveBytesThreshold来确认收到一定是固定长度的数据,指定的结果就是可能刚开始正常,过一段时间就会出现问题。
展开全部
用RecieveBytesThreshold=47是不靠谱的,实际调试时你会发现有时候缓冲区不到47字节就触发中断,所以一定要把RecieveBytesThreshold设为默认的1。即使你把他设成1,也会发现触发中断时缓冲区里面字节数还是可能大于1,不过这样能确保数据接收完整(47个你全部能收到)。
数据接收与处理逻辑要在RecieveBytesThreshold=1的基础上来建立,比如你可以在每次接收中断中把缓冲区的字节以续接的方式存在一个暂存数组里,等到拼满47个,就统一做一次处理。
数据接收与处理逻辑要在RecieveBytesThreshold=1的基础上来建立,比如你可以在每次接收中断中把缓冲区的字节以续接的方式存在一个暂存数组里,等到拼满47个,就统一做一次处理。
本回答被网友采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询