亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

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 關注
  • 271 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號