C#串行端口读取 - 获取具有不同Lenght的COBS编码消息



所以我在c#编程中进行了新。我已经在Visual Studio中编程了C#表单应用程序,以与串行端口上的设备进行通信/初始化。设备之间的通信是COBS编码的,因此除每个消息末尾外,没有0x00字节。发送和接收的消息的长度不同。

我的问题目前是,我收到的消息尚未完成或从消息中间开始,因此我无法在接收到的消息中触发以特定值发送的消息。您可以用接收到的0x00确定消息的结尾(0x00表示COBS编码数据中的消息结束)

所以我需要的是处理完整消息,并将其放入字节数组中以分析特定值的字节[11]。

这是我到目前为止所做的:

    private bool   b_portopen = false;
    private byte[] b_rcv_buffer = new byte[256];
    private void button1_Click(object sender, EventArgs e) {
            //InitTimer();
            if (b_portopen == false)
            {
                serialPort1.PortName = comboBox1.SelectedItem.ToString();
                serialPort1.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
                serialPort1.Open();
                b_portopen = true;
                button1.Text = "Close";
                button2.Enabled = true;
                Console.WriteLine("Serial Port Opened");
            }
            else if (b_portopen == true)
            {
                serialPort1.Close();
                b_portopen = false;
                button1.Text = "Open";
                button2.Enabled = false;
                Console.WriteLine("Serial Port Closed");
            }
        }
private async void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
        {
            serialPort1.Read(b_rcv_buffer, 0, 256);
            //serialPort1.Read(b_rcv_buffer1, 11, 2);
            richTextBox1_receive.Invoke(new Action(() =>
            {
                richTextBox1_receive.AppendText(BitConverter.ToString(b_rcv_buffer) + "n");
                richTextBox1_receive.ScrollToCaret();
            }));
            switch (b_rcv_buffer[10])
            {
                case b_state_startup:
                    do something
                case b_state_be_start_conf:
                    do something
                case b_state_keepalive_conf:
                    do something
                case b_state_unprepare_conf:
                    do something
                case b_state_prepare_conf:
                    do something

            }

        }

所以,我找到了使用Consurrentqueue的解决方案:

    ConcurrentQueue<byte> b_rcv_buffer = new ConcurrentQueue<byte>();
    private Timer timer2;
    public void InitTimer()
            {
                timer2 = new System.Windows.Forms.Timer();
                timer2.Tick += new EventHandler(timer2_Tick);
                timer2.Interval = 1; // in miliseconds
                timer2.Start();
            }
    private async void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
        {
            int bytes = serialPort1.BytesToRead;
            byte[] buf = new byte[bytes];
            serialPort1.Read(buf, 0, serialPort1.BytesToRead);
            for(int i = 0; i < buf.Length; i++)
            {
                b_rcv_buffer.Enqueue(buf[i]); //Enqueue every received Byte in Concurrentqueue
            }
        }
private async void timer2_Tick(object sender, EventArgs e)
        {
            if (b_rcv_buffer.Contains<byte>(0x00))
            {
                byte[] array = b_rcv_buffer.ToArray();
                richTextBox1_receive.Invoke(new Action(() =>
                {
                    richTextBox1_receive.AppendText(BitConverter.ToString(array) + "n");
                    //richTextBox1_receive.ScrollToCaret();
                }));            
                byte ignored;
                while (b_rcv_buffer.TryDequeue(out ignored));
        }

最新更新