C # wait for an echo on the serial port, check it and have a time limit while waiting

Hello and thank you for considering this issue: I send a command from a PC via a virtual serial port to the embedded system, which returns the command when the embedded system completed the command.

I can send the command in order and see an echo when the command is completed by the embedded system, but I had trouble finding a suitable way to wait or delay the program until an echo command is received so that I can continue and send the next command . I believe this is the type of "high level" flow control I'm trying to implement. The code is in C #. I would like to wait from the echo and have a timeout, in case of loss of connection between the PC and the embedded system, so that the program does not freeze. Any wizz kids that can offer a neat way to do this? I'm not a great C # programmer, just learning.

This is the receive function that I have:

    private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        // If the com port has been closed, do nothing
        if (!comport.IsOpen) return;

        // This method will be called when there is data waiting in the port buffer

        // Determain which mode (string or binary) the user is in
        if (CurrentDataMode == DataMode.Text)
        {
            // Read all the data waiting in the buffer
            string data = comport.ReadExisting();

            // Display the text to the user in the terminal
            Log(LogMsgType.Incoming, data);
        }
        else
        {
            // Obtain the number of bytes waiting in the port buffer
            int bytes = comport.BytesToRead;

            // Create a byte array buffer to hold the incoming data
            byte[] buffer = new byte[bytes];

            // Read the data from the port and store it in our buffer
            comport.Read(buffer, 0, bytes);

            // Show the user the incoming data in hex format
            Log(LogMsgType.Incoming, ByteArrayToHexString(buffer));
            }
    }

This is an example of calling the Transmitt command:

     text = "AR" + 50 + "\r";            //transmit a command to move
     this.comport.Write(text);

[Thread.Sleep(TIMEGAP)] , , :

     text = "AR" + 50 + "\r";            //transmit a command to move
     this.comport.Write(text);
     Thread.Sleep(TIMEGAP);              //Timegap = 10000ms

[Thread.Sleep(TIMEGAP)] /, , , , , , [AR50\r ] , , 5 , .

?

!

+5
1

- DataReceived, ReadTimeout Read.

ASCII, ReadLine.

TimeoutException, ReadTimeout .

, , , . , , ManualResetEvent, . ManualResetEvent . , lock.

GC , , , - :

using System.Text;
using System.IO.Ports;
using System.Threading;

namespace ConsoleApplication2
{
    class Program
    {
        static string serialBuffer = "";
        static string expectedEcho = null;
        static object expectedEchoLock = new object();
        static ManualResetEvent expectedEchoReceived = new ManualResetEvent(false);
        static SerialPort port = new SerialPort("COM1", 19200, Parity.None, 8, StopBits.One);

        static void Main(string[] args)
        {
            port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
        }

        static void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            while (port.BytesToRead > 0)
            {
                byte[] buffer = new byte[port.BytesToRead];
                int bytesRead = port.Read(buffer, 0, buffer.Length);
                if (bytesRead <= 0) return;
                serialBuffer += Encoding.UTF8.GetString(buffer, 0, bytesRead);
                string[] lines = serialBuffer.Split('\r', '\n');
                // Don't process the last part, because it not terminated yet
                for (int i = 0; i < (lines.Length - 1); i++)
                {
                    if (lines[i].Length > 0)
                        ProcessLine(lines[i]);
                }
                serialBuffer = lines[lines.Length - 1]; // keep last part
            }
        }

        static void ProcessLine(string line)
        {
            bool unsolicitedMessageReceived = false;
            lock (expectedEchoLock)
            {
                if (line == expectedEcho)
                {
                    expectedEchoReceived.Set();
                }
                else
                {
                    unsolicitedMessageReceived = true;
                }
            }
            if (unsolicitedMessageReceived)
            {
               // Process unsolicited/unexpected messages
            }
        }

        /// <summary>
        /// Send a command and wait for echo
        /// </summary>
        /// <param name="command">The command to send</param>
        /// <returns>True when echo has been received, false on timeout.</returns>
        static bool SendCommand(string command)
        {
            lock (expectedEchoLock)
            {
                expectedEchoReceived.Reset();
                expectedEcho = command;
            }
            port.Write(command);
            return expectedEchoReceived.WaitOne(5000); // timeout after 5 seconds
        }
    }
}
+6

All Articles