简体   繁体   English

C#串口有条件和部分读取

[英]C# Serial Port Conditional & Partial Reading

I am stumped. 我感到难过。 Searched myself blue in the face - no go. 搜索自己脸色发青-不行。

I am trying to establish serial comms with a device that sends 2 different blocks of data (one after the other) every 1 second continuously. 我正在尝试与一种设备建立串行通信,该设备每1秒连续发送2个不同的数据块(一个接一个)。 The first block starts with "PID" and the second block ends with "H18". 第一个块以“ PID”开头,第二个块以“ H18”结尾。

I only need to read once every 5 seconds. 我只需要每5秒钟阅读一次。

My problem is two fold: 我的问题有两个:

  1. I have no idea/control when the read starts and often starts mid - block. 我不知道/什么时候开始读取并且经常从中间开始读取。
  2. I have no control over the start and end cycle to ensure I get a full two blocks as I need both. 我无法控制开始和结束周期,以确保我同时需要两个完整的块。

Both blocks are about 200 characters long in total, has no /r at the beginning and has /r/n in between various items. 这两个块的总长度约为200个字符,开头没有/ r,并且在各个项目之间都有/ r / n。

I have tried doing two subsequent reads but no success. 我尝试进行两次后续读取,但未成功。 Tried playing with StartsWith and EndsWith but they are not recognized? 尝试过与StartsWith和EndsWith一起玩,但是无法识别? The code has been all over the show, but here is the base I am working from currently: 该代码已遍及整个展览,但以下是我目前正在从事的工作:

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;
                //}
              }
         }
    }

and

 /// 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();

Please help me - I am fairly new to C# and have struggled for 4 days with this? 请帮助我-我对C#还是很陌生,为此已经挣扎了4天?

Is this a GUI application or a background service? 这是GUI应用程序还是后台服务? Either way, ditch DataReceived event and use ReadAsync , as I showed in my blog post . 无论哪种方式,都ReadAsync DataReceived事件并使用ReadAsync ,正如我在博客文章中所展示的那样 Then, buffer all incoming data into a List<byte> (this easily deals with messages which arrive split into two), and implement some synchronization logic. 然后,将所有传入数据缓冲到List<byte> (这很容易处理分成两部分的消息),并实现一些同步逻辑。

Here's an outline of how synchronization works: 这是同步工作原理的概述:

  1. loop through the List<byte> , find the beginning of a message 遍历List<byte> ,找到消息的开头
  2. determine whether the entire message has been received 确定是否已收到整个消息
  3. copy the message payload and fire off an event so the business logic that acts on the message can be separate from the buffering/parsing logic 复制消息有效负载并触发事件,以便可以将作用于消息的业务逻辑与缓冲/解析逻辑分开
  4. remove bytes from the list up to the end of the detected message 从列表中删除字节,直到检测到的消息的末尾
  5. search the remainder of the buffer for more valid messages (repeat 1-4) 在缓冲区的其余部分中搜索更多有效消息(重复1-4)
  6. when the buffer List<byte> doesn't contain a complete message, call ReadAsync again 当缓冲区List<byte>不包含完整的消息时,再次调用ReadAsync

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM