我的text显示总是会时不时的显示0.0 是不是经常丢包的问题啊

小学工 2017-07-22 10:31:18


下位机发送的命令
5A A5 05 82 10 01 00 09
5A A5 为包头
10 01 为地址位
00 09 为数据位

这是在触发事件里的代码
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{

SerialPort serialPort1 = sender as SerialPort;
byte[] shuju = new byte[serialPort1.ReadBufferSize];
serialPort1.Read(shuju, 0, shuju.Length);

if (shuju[0] == 0x5A && shuju[1] == 0xA5)
{
if (shuju[5] == 0x01)
{
{
label8.Text = ((double)(shuju[6] * 256 + shuju[7]) / 10).ToString("f1");

}
}
}}

这样的话在控件的显示里会一直跳0.0 , 显示的数据很不稳定 , 现在是测试数据位的00 09 是不会变的. 是什么原因导致的? 求解
























...全文
398 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
小学工 2017-07-23
  • 打赏
  • 举报
回复
引用 7 楼 xian_wwq 的回复:
[quote=引用 6 楼 qq_38606415 的回复:] [quote=引用 5 楼 xian_wwq 的回复:] 把shuju.Length打印出来 先保证接收数据长度是够的
怎么打印出来shuju.length啊 数据位的长度一直是8字节 而接受过来的数据长度是不断接受不断增加的 会不会是缓存区满了之后 接受的数据溢出 而导致部分数据接收不全?[/quote] ReceiveBytesThreshold属性是设置串口输入缓冲区中的数据字节大于ReceiveBytesThreshold时触发DataReceived事件 可以根据自己业务特点进行设置 这样可以保证接收的数据是满足解包条件的 如果担心是接收太慢,那么把数据解析的代码先屏蔽掉,直接显示

           SerialPort sp = sender as SerialPort;
            string serialReadString = sp.ReadExisting();
            label8.Invoke(
                new MethodInvoker
                    (
                      delegate
                      {
                          this.label8.Text=serialReadString;
                      }
                    )
                );
[/quote] 我的ReceiveBytesThreshold属性是设置的1 只要接收到一个字节就触发了 我把数据的处理放到了新线程里

SerialPort serialPort1 = sender as SerialPort;
 string serialll = serialPort1.ReadExisting();
 byte[] shuju = new byte[serialPort1.ReadBufferSize];
 serialPort1.Read(shuju, 0, shuju.Length);


 if (shuju[0] == 0x5A && shuju[1] == 0xA5)
            {
                if (shuju[4] == 0x10 && shuju[5] == 0x01)
                {
                  {
                          string pp = ((double)(shuju[6] * 256 + shuju[7]) / 10).ToString("f1");
                             label8.Invoke(new MethodInvoker(delegate
                                {
                                    label8.Text = pp;
                                }
                                ));
                    }
                }}

这样貌似不行 哪里错了
小学工 2017-07-23
  • 打赏
  • 举报
回复
引用 9 楼 sp1234 的回复:
你就算是把 shuju 数组定义为 100万字节,那么其中有多少字节是真实有效的,也要看 Read 函数返回的 int 值而定。 你对于 Read(....) 时会经历的数据分包粘包概念,完全没搞懂。
对于分包粘包不是很清楚 只知道把包接受过来就进行处理 在网上找的资源讲解的也很模糊 对这一块的概念不是很清楚
小学工 2017-07-23
  • 打赏
  • 举报
回复
引用 7 楼 xian_wwq 的回复:
[quote=引用 6 楼 qq_38606415 的回复:] [quote=引用 5 楼 xian_wwq 的回复:] 把shuju.Length打印出来 先保证接收数据长度是够的
怎么打印出来shuju.length啊 数据位的长度一直是8字节 而接受过来的数据长度是不断接受不断增加的 会不会是缓存区满了之后 接受的数据溢出 而导致部分数据接收不全?[/quote] ReceiveBytesThreshold属性是设置串口输入缓冲区中的数据字节大于ReceiveBytesThreshold时触发DataReceived事件 可以根据自己业务特点进行设置 这样可以保证接收的数据是满足解包条件的 如果担心是接收太慢,那么把数据解析的代码先屏蔽掉,直接显示

           SerialPort sp = sender as SerialPort;
            string serialReadString = sp.ReadExisting();
            label8.Invoke(
                new MethodInvoker
                    (
                      delegate
                      {
                          this.label8.Text=serialReadString;
                      }
                    )
                );
[/quote] 可是我的数据包接受过来是需要处理之后再显示的 我应该把处理放在哪呢 是一定要建立一个数组的 要不我没法提取数组里的数进行运算
exception92 2017-07-23
  • 打赏
  • 举报
回复
引用 4 楼 qq_38606415的回复:
[quote=引用 2 楼 duanzi_peng 的回复:] serialPort1_DataReceived并非在主线程上触发,你的lable属于UI线程,使用invoke方法进行赋值。
还有 invoke方法 是要用委托么 [/quote] 是的,就像7楼那样。
  • 打赏
  • 举报
回复
你就算是把 shuju 数组定义为 100万字节,那么其中有多少字节是真实有效的,也要看 Read 函数返回的 int 值而定。 你对于 Read(....) 时会经历的数据分包粘包概念,完全没搞懂。
  • 打赏
  • 举报
回复
引用 6 楼 qq_38606415 的回复:
[quote=引用 5 楼 xian_wwq 的回复:] 把shuju.Length打印出来 先保证接收数据长度是够的
怎么打印出来shuju.length啊 数据位的长度一直是8字节 而接受过来的数据长度是不断接受不断增加的 会不会是缓存区满了之后 接受的数据溢出 而导致部分数据接收不全?[/quote] 人家是让你打印出 serialPort1.Read(....) 函数返回的、真实的数据长度,而你说的是 ReadBufferSize 长度为8字节(实际上有几十K字节更好),完全是两回事。
小学工 2017-07-23
  • 打赏
  • 举报
回复

 private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
SerialPort serialPort1 = sender as SerialPort;
byte[] shuju = new byte[serialPort1.ReadBufferSize];
 serialPort1.Read(shuju, 0, shuju.Length);

 if (shuju[0] == 0x5A && shuju[1] == 0xA5)
            {
                if (shuju[4] == 0x10 && shuju[5] == 0x01)
                {
                  {
                           
                             label8.Invoke(new MethodInvoker(delegate
                                {
                                    label8.Text = ((double)(shuju[6] * 256 + shuju[7]) / 10).ToString("f1"); ;
                                }
                                ));
                    }
                }
}
}

我这样在别的线程启用 可以么
xian_wwq 2017-07-23
  • 打赏
  • 举报
回复
完整的包至少是8字节, 但并不是每次都能收到8字节, 如果不够,那么随后进行的解包是毫无意义的, 必须要等到接收完整才能进行下一步的处理。 我建议把接收到的打印出来, 并不是为了打印而打印,只是为了定位问题 [/code][/quote]
引用 12 楼 qq_38606415 的回复:
[quote=引用 9 楼 sp1234 的回复:] 你就算是把 shuju 数组定义为 100万字节,那么其中有多少字节是真实有效的,也要看 Read 函数返回的 int 值而定。 你对于 Read(....) 时会经历的数据分包粘包概念,完全没搞懂。
对于分包粘包不是很清楚 只知道把包接受过来就进行处理 在网上找的资源讲解的也很模糊 对这一块的概念不是很清楚[/quote]
引用 12 楼 qq_38606415 的回复:
[quote=引用 9 楼 sp1234 的回复:] 你就算是把 shuju 数组定义为 100万字节,那么其中有多少字节是真实有效的,也要看 Read 函数返回的 int 值而定。 你对于 Read(....) 时会经历的数据分包粘包概念,完全没搞懂。
对于分包粘包不是很清楚 只知道把包接受过来就进行处理 在网上找的资源讲解的也很模糊 对这一块的概念不是很清楚[/quote]
小学工 2017-07-22
  • 打赏
  • 举报
回复
求思路 一直搞不明白原因
xian_wwq 2017-07-22
  • 打赏
  • 举报
回复
引用 6 楼 qq_38606415 的回复:
[quote=引用 5 楼 xian_wwq 的回复:] 把shuju.Length打印出来 先保证接收数据长度是够的
怎么打印出来shuju.length啊 数据位的长度一直是8字节 而接受过来的数据长度是不断接受不断增加的 会不会是缓存区满了之后 接受的数据溢出 而导致部分数据接收不全?[/quote] ReceiveBytesThreshold属性是设置串口输入缓冲区中的数据字节大于ReceiveBytesThreshold时触发DataReceived事件 可以根据自己业务特点进行设置 这样可以保证接收的数据是满足解包条件的 如果担心是接收太慢,那么把数据解析的代码先屏蔽掉,直接显示

           SerialPort sp = sender as SerialPort;
            string serialReadString = sp.ReadExisting();
            label8.Invoke(
                new MethodInvoker
                    (
                      delegate
                      {
                          this.label8.Text=serialReadString;
                      }
                    )
                );
小学工 2017-07-22
  • 打赏
  • 举报
回复
引用 5 楼 xian_wwq 的回复:
把shuju.Length打印出来 先保证接收数据长度是够的
怎么打印出来shuju.length啊 数据位的长度一直是8字节 而接受过来的数据长度是不断接受不断增加的 会不会是缓存区满了之后 接受的数据溢出 而导致部分数据接收不全?
xian_wwq 2017-07-22
  • 打赏
  • 举报
回复
把shuju.Length打印出来 先保证接收数据长度是够的
小学工 2017-07-22
  • 打赏
  • 举报
回复
引用 2 楼 duanzi_peng 的回复:
serialPort1_DataReceived并非在主线程上触发,你的lable属于UI线程,使用invoke方法进行赋值。
还有 invoke方法 是要用委托么
小学工 2017-07-22
  • 打赏
  • 举报
回复
引用 2 楼 duanzi_peng 的回复:
serialPort1_DataReceived并非在主线程上触发,你的lable属于UI线程,使用invoke方法进行赋值。
可否能说的详细点 新手懂得不多 你的意思是说把lable放在新建的线程么
exception92 2017-07-22
  • 打赏
  • 举报
回复
serialPort1_DataReceived并非在主线程上触发,你的lable属于UI线程,使用invoke方法进行赋值。

110,539

社区成员

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

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

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