当前位置: 代码迷 >> C# >> C#串口通信实时数据统计解决办法
  详细解决方案

C#串口通信实时数据统计解决办法

热度:81   发布时间:2016-05-05 04:39:40.0
C#串口通信实时数据统计
现在使用SerialPort控件接收从串口过来的数据,使用的是SerialPort的DataReceived,DataReceived是在辅助线程里面的,现在的情况是可以正常的发送、接收到数据。但需要统计发送、接收的数据数目(以条为单位),并实时计算两者之差,并反映到Textbox控件上,遇到的问题是我需要在接收完后才将两值相减,而不是一边发送一边计算差值(这样会在TextBox上的值不停闪烁,不满足要求),也就是在发送、并确认接收到所有数据后在计算差值!菜鸟一枚,求指教,在编写过程中总感觉无法实现实时的发送减去接收的数据,因为发送和接收属于不同的线程,接收数据的统计值无法实现实时的回传。。。希望解决了的能贴出源代码,感激不尽!
------解决思路----------------------
那是因为,你发送完,到接收之前,这个通信等待时间长
而你接收完,到下一次发送,这个间隔时间短

那么如果你在发送和接收都分别进行一次计算并把结果全部显示到界面上,这个数字就会不停的在1和0之间变化,并且显示1的时间会比显示0的时间长很多,眼睛基本看不出它什么时候会变成0

所以你应该重新设计方案,而不是纠结技术
------解决思路----------------------
你的电脑太快了。。。你休眠一下接收发送线程试试
------解决思路----------------------
你发送后立马就在计算MultlossRate_one的值是不可靠的(居然你注释中说发送数据成功后,会立马接收),当你发送的时候,数据只是扔进串口的FIFO中,串口再按”位“发送出去,接收也是一样按位接收,而且发送和接收的速度跟波特率有关。但是肯定比你发送后立即计算MultlossRate_one的时间长,而你用断点调试时其实就是一个延时等待数据应答的过程。

你可以先试着在在计算前加一定时间延时,确保数据应答的时间。
Thread.Sleep(100);  // 根据你的响应时间。
MultlossRate_one = MultSendcount_one - MultReceivecount_one;//关键是此处的差值计算???

其实并不推荐你用这种方法,这样想连续发送的时候就会出现卡顿现象,其实你可以别开一个线程,定时计算这个值并显示,比如间隔500毫秒计算一次然后显示,实时刷新差值。
------解决思路----------------------
楼主你虽然Send 后   MultSendcount_one++; 这是发送算一次,但serialPort1_DataReceived  这个会有问题
因为serialPort1_DataReceived 接收一组数据会发生  触发一次,或多次就是说如
111111111122222 这样的数据 他可能会一次性111111111122222 全接收完,那你上面的MultReceivecount_one +1 
但因为下位机缓冲数据 会把数据 分成两段像这样111111111    与 122222 那你MultReceivecount_one 变成了2了
也就是你发了一次,触发却是1或两次或三次的,就造成了你发送接收次数不对等了。

------解决思路----------------------
你可以这个做
数据差=0显示0
数据差=1不着急更改显示,而是在日志中显示,数据已经发送,等待接收.如果后面接收到了.显示数据已经收到
这样数据差在1条以内的时候就不会显示问题了.
如果数据差超过1条,显示数字N-1,并且显示在日志中显示,数据已经发送.最终查询日志会发现某条数据只有发送没有接收.
------解决思路----------------------
引用:
哦,没有这样想到过,也不太懂怎么利用时间计时器去处理(菜鸟一枚),但会学习的,希望这样可以解决,多谢。。。

从工具箱里拖个timer控件,放到窗体中,设置它的enable属性为true,设置时间间隔(默认100)改成1000
然后在里面做差并显示,完事
------解决思路----------------------
引用:
Quote: 引用:

当然你需要先双击它,生成timer1_tick这个回调函数,在回调函数里写代码

嗯,好的,原来是这样,学习了。。。多谢!


LZ 能不能问一下  我如果想把 固定的一串“02H 30H 30H 31H 30H 30H 30H 31H 03H 35H 35H”  发给串口 应该怎么发啊?
------解决思路----------------------
引用:
LZ 不好意思哈  借用你的地方一下,  也就是说 02H = 0x02    35H=0x35  这种么?

是的
在数学里,H结尾或0x开头都表示16进制,不过在C#语法里只认识0x开头,不认识H结尾的写法
------解决思路----------------------
楼主很谦虚.
我说一个不太成熟度的建议:
不用 DataReceived 事件来接收.
发送玩之后同步Read方法来接收数据(设定超时时间)

好吧,或许真的很不成熟
  相关解决方案