Laden...

Forenbeiträge von CSharpEntwickler Ingesamt 4 Beiträge

03.06.2022 - 11:15 Uhr

Hallo,

ich habe nun den Empfang der Daten in einer separaten Task realisiert.
Auch das Versenden von Daten läuft in einem anderen Task.
Nun ist es so wenn ich Daten versende, dann läuft das mit dem Empfangen von Daten schief.


           bool SendFlagLedOn = false;
           bool SendFlagLedOff = false;           

           Task recvTask = new Task(new Action(OnRxFrames));
            recvTask.Start();

            Task sendTask = new Task(new Action(OnTxFrames));
            sendTask.Start();


private void OnRxFrames()
        {
            while (true)
            {
                if (recvByteCnt == 0)
                {
                    recvLength = GetByteFromDevice();
                    recvByte = recvLength;
                }
                else
                {
                    recvByte = GetByteFromDevice();
                }

                recvBuffer[recvByteCnt] = recvByte;

                if (recvByteCnt >= recvLength)
                {
                    recvFlag = 1;
                    recvByteCnt = 0;

                    Debug.Write("Complete\n");

                    this.Invoke(new EventHandler(DoUpDate));
                }
                else
                {
                    recvByteCnt++;
                }
            }
        }

        private void OnTxFrames()
        {
            while (true)
            {
                if(SendFlagLedOn == true)
                {
                    SendFlagLedOn = false;

                    byte[] txData = new byte[5];
                    txData[0] = 4;
                    txData[1] = 1;
                    txData[2] = 2;
                    txData[3] = 3;
                    txData[4] = 4;

                    string str = Encoding.Default.GetString(txData);
                    mySerialPort.Write(str);
                }

                if (SendFlagLedOff == true)
                {
                    SendFlagLedOff = false;

                    byte[] txData = new byte[5];
                    txData[0] = 4;
                    txData[1] = 2;
                    txData[2] = 2;
                    txData[3] = 3;
                    txData[4] = 4;

                    string str = Encoding.Default.GetString(txData);
                    mySerialPort.Write(str);
                }
            }
        }

02.06.2022 - 11:14 Uhr

Hallo Abt, danke für deinen Post.

Ich habe für meine Anwendung BlockingCollection benutzt. Im Thread lese ich dann die bytes mit der Methode GetByteFromDevice aus.

Also wäre in meinem Fall die andere Variante geeigneter?

02.06.2022 - 11:08 Uhr

Da hätte ich noch eine weitere Frage.

Wo ist der Unterscheid zwischen ConcurrentQueue und BlockingCollection?


     fifo_peekonly = new ConcurrentQueue<byte>();
     fifo_queue = new BlockingCollection<byte>(fifo_peekonly);

Dies habe ich von folgenden Link herausgezogen für mein Projekt:
c-sharp-serial-port-sometimes-missing-data/45432817#45432817

02.06.2022 - 10:49 Uhr

Hallo,

ich habe eine kleine GUI in C# erstellt. Mit dieser Gui werden/sollen Daten vom Mikrocontroller ausgelesen werden.
Es handelt sich um serielle Daten. Im Programm nutze ich die Bibliothek Syste.IO.Ports.


        private void btn_Init_Click(object sender, EventArgs e)
        {
            mySerialPort = new SerialPort("COM5");

            mySerialPort.BaudRate = 115200;
            mySerialPort.Parity = Parity.None;
            mySerialPort.StopBits = StopBits.One;
            mySerialPort.DataBits = 8;
            mySerialPort.Handshake = Handshake.None;
            mySerialPort.ReadTimeout = 100;

            //mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
            mySerialPort.Open();

            fifo_peekonly = new ConcurrentQueue<byte>();
            fifo_queue = new BlockingCollection<byte>(fifo_peekonly);

            mySerialPort.DataReceived += (sender, e) =>
            {
                byte[] buffer = new byte[mySerialPort.BytesToRead];
                if (!mySerialPort.IsOpen)
                {
                    throw new System.InvalidOperationException("Serial port is closed.");
                }
                mySerialPort.Read(buffer, 0, mySerialPort.BytesToRead);
                foreach (var b in buffer)
                    fifo_queue.Add(b);
            };

            Thread thr = new Thread(new ThreadStart(mythread));
            thr.Start();
        }

        public byte GetByteFromDevice()
        {
            byte b;
            b = fifo_queue.Take();
            return b;
        }

       public void mythread()
        {
            while(true)
            {
                if(recvByteCnt == 0)
                {
                    recvLength = GetByteFromDevice();
                    recvByte = recvLength;
                }
                else
                {
                    recvByte = GetByteFromDevice();
                }

                recvBuffer[recvByteCnt] = recvByte;

                if (recvByteCnt >= recvLength)
                {
                    recvFlag = 1;
                    recvByteCnt = 0;

                    Debug.Write("Complete\n");
                }
                else
                {
                    if (recvByteCnt == 0)
                    {
                        Debug.Write("Start timeout\n");
                    }
                    recvByteCnt++;
                }

                //Debug.Write(recvByte.ToString() + "\n");
            }
        }


Nun fehlt quasi noch eine TimeOut Mechanismus. Dieser soll im thread nach der if Bedingung "if (recvByteCnt == 0)" eingesetzt werden.
Wie würde man solch eine Funktionalität realisieren?