为了账号安全,请及时绑定邮箱和手机立即绑定

C# Serial Port Read - 获取不同长度的 COBS 编码消息

C# Serial Port Read - 获取不同长度的 COBS 编码消息

C#
哈士奇WWW 2022-10-23 16:06:31
所以我是 C# 编程的新手。我在 Visual Studio 中编写了一个 C# Forms 应用程序,以通过串行端口与设备通信/初始化设备。设备之间的通信是 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            }        }
查看完整描述

1 回答

?
侃侃尔雅

TA贡献1801条经验 获得超16个赞

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


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

        }


查看完整回答
反对 回复 2022-10-23
  • 1 回答
  • 0 关注
  • 225 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号