C#串口有条件&部分阅读

时间:2015-10-27 15:18:57

标签: c# .net serial-port

我很难过。在脸上搜寻自己的蓝色 - 没有去。

我正在尝试与设备建立串行通信,该设备每1秒连续发送2个不同的数据块(一个接一个)。第一个块以" PID"开头。第二个块以" H18"

结束

我只需要每5秒阅读一次。

我的问题有两个:

  1. 我不知道/控制何时开始读取并经常在中间阻止。
  2. 我无法控制开始和结束周期,以确保我得到满两个块,因为我需要两个。
  3. 两个块总共大约200个字符,开头没有/ r,各个项目之间有/ r / n。

    我尝试过两次后续读取但没有成功。尝试使用StartsWith和EndsWith,但他们不被识别?代码已遍布整个节目,但这是我目前工作的基础:

    static void DataReceivedHandlerbat(object sender,     SerialDataReceivedEventArgs e)
        {
            var batm = sender as SerialPort;
            if ((batm != null) && (!_gotResponse))
            {
             while (stringb.Length < 200)
                {
                    byte[] buffer = new byte[batm.BytesToRead];
                    int numRead = batm.Read(buffer, 0, buffer.Length);
                    stringb.Append(System.Text.Encoding.ASCII.GetString(buffer));
    
                   // if (stringb.S  == 0)
                    //{
                      //   _gotResponse = true;
                        // break;
                    //}
                  }
             }
        }
    

     /// Obtain Battery string
    
                SerialPort batm = new SerialPort();
                batm.PortName = "com4";
                batm.BaudRate = 19200;
                batm.DataBits = 8;
                batm.Parity = Parity.None;
                batm.StopBits = StopBits.One;
    
                batm.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandlerbat);
    
                batm.Open();
    
                //batm.ReadExisting();
    
                int timeoutMsb;
                timeoutMsb = 1000;
    
                var startTimeb = DateTime.Now;
                while (!_gotResponse && ((DateTime.Now - startTimeb).TotalMilliseconds < timeoutMsb))
                {
                    Thread.Sleep(20);
                }
    
                batm.Close();
    
                _gotResponse = false;
    
                //Build Battery String
    
                String bat = stringb.ToString();
    

    请帮助我 - 我对C#相当新,并且已经用这个来挣扎4天了?

1 个答案:

答案 0 :(得分:0)

这是GUI应用程序还是后台服务?无论哪种方式,抛弃DataReceived事件并使用ReadAsync,因为我展示了in my blog post。然后,将所有传入的数据缓冲到List<byte>(这很容易处理分成两部分的消息),并实现一些同步逻辑。

以下是同步工作原理的概述:

  1. 循环浏览List<byte>,找到消息的开头
  2. 确定是否已收到整个邮件
  3. 复制消息有效负载并触发事件,以便作用于消息的业务逻辑可以与缓冲/解析逻辑分开
  4. 从列表中删除字节,直到检测到的消息结束
  5. 在缓冲区的剩余部分搜索更多有效消息(重复1-4)
  6. 当缓冲区List<byte>未包含完整邮件时,请再次致电ReadAsync