繁体   English   中英

串行端口数据接收事件处理程序的可靠性

[英]Serial Port Data Received Event Handler Reliability

我正在使用C#中的串行端口功能与硬件进行通信。 一切都很好地写入了串行端口,并且串行端口始终处于连接状态。

出于某种原因,“串行端口数据接收处理程序”并不总是读取即将出现的数据(8次中的1次都无法读取任何内容或调用事件函数本身)。 另一方面,一切都很好。 我只收到来自串行端口的1、2、3等一个字母

这是我的代码:

串行设置:

    //Create new serial port
    SerialPort SerPort = new SerialPort("COM4");

    private void SetupSerial()
    {
        SerPort.BaudRate = 9600;
        SerPort.Parity = Parity.None;
        SerPort.StopBits = StopBits.One;
        SerPort.DataBits = 8;
        SerPort.Handshake = Handshake.None;
        SerPort.ReadTimeout = 4000;
        SerPort.WriteTimeout = 6000;
        SerPort.Open();
        SerPort.DataReceived += new SerialDataReceivedEventHandler(HandleSerialData);

        lblStatus.Text = "Successfully connected to COM port with no errors!";

    }

我的写入串行功能:

       private void WriteToSerial( string data )
    {
        byte[] MyMessage = Encoding.UTF8.GetBytes(data);
        SerPort.Write(MyMessage, 0, MyMessage.Length);

        string time = "[" + DateTime.Now.ToString("HH:mm") + "]";

        bool debug = chkDebug.Checked;
        if (debug ) f.DebugText = time + " Wrote bytes to serial: " + data;
    }

我的接收事件功能:

    //Called everytime serial data is recieved
    private void HandleSerialData(object sender, SerialDataReceivedEventArgs e)
    {
        try
        {
            //Store recieved data in variable
            SerialPort sp = (SerialPort)sender;
            string data = sp.ReadExisting().ToString();

            bool debug = chkDebug.Checked;

            string time = "[" + DateTime.Now.ToString("HH:mm") + "]";
            if( debug ) f.DebugText = time + " Recieved serial data: " + data;

            switch ( data )
            {
                case "1":
                //If Battery is already on
                if( Battery1[0] == "ON")
                {
                    Battery1[0] = "OFF"; //ON or OFF
                    Battery1[2] = DateTime.Now.ToString("h:mm tt"); //End time
                    WriteLogFile("1");
                    lblST1.Text = "n/a";
                    lblET1.Text = "n/a";
                    if (debug) f.DebugText = time + " Battery 1 testing switched OFF.";
                }
                else
                {
                    Battery1[0] = "ON"; //ON or OFF
                    Battery1[1] = DateTime.Now.ToString("h:mm tt"); //Start time
                    Battery1[5] = DateTime.Now.ToString("d/MM/yyyy"); //Start date
                    plcRespond = true;
                    lblST1.Text = Battery1[1];
                        if (debug) f.DebugText = time + " Battery 1 testing switched ON.";
                }
                break;

                case "2":
                //If Battery is already on
                if (Battery2[0] == "ON")
                {
                    Battery2[0] = "OFF";
                    Battery2[2] = DateTime.Now.ToString("h:mm tt"); //End time
                    WriteLogFile("2");
                    lblST2.Text = "n/a";
                    lblET2.Text = "n/a";
                        if (debug) f.DebugText = time + " Battery 2 testing switched OFF.";
                }
                else
                {
                    Battery2[0] = "ON"; //ON or OFF
                    Battery2[1] = DateTime.Now.ToString("h:mm tt"); //Start time
                    Battery2[5] = DateTime.Now.ToString("d/MM/yyyy"); //Start date
                    plcRespond = true;
                    lblST2.Text = Battery2[1];
                        if (debug) f.DebugText = time + " Battery 2 testing switched ON.";
                }
                break;

                case "3":
                //If Battery is already on
                if (Battery3[0] == "ON")
                {
                    Battery3[0] = "OFF"; //ON or OFF
                    Battery3[2] = DateTime.Now.ToString("h:mm tt"); //End time
                    WriteLogFile("3");
                    lblST3.Text = "n/a";
                    lblET3.Text = "n/a";
                        if (debug) f.DebugText = time + " Battery 3 testing switched OFF.";
                }
                else
                {
                    Battery3[0] = "ON"; //ON or OFF
                    Battery3[1] = DateTime.Now.ToString("h:mm tt"); //Start time
                    Battery3[5] = DateTime.Now.ToString("d/MM/yyyy"); //Start date
                    plcRespond = true;
                    lblST3.Text = Battery3[1];
                        if (debug) f.DebugText = time + " Battery 3 testing switched ON.";
                }
                break;

                case "4":
                //If Battery is already on
                if (Battery4[0] == "ON")
                {
                    Battery4[0] = "OFF"; //ON or OFF
                    Battery4[2] = DateTime.Now.ToString("h:mm tt"); //End time
                    WriteLogFile("4");
                    lblST4.Text = "n/a";
                    lblET4.Text = "n/a";
                        if (debug) f.DebugText = time + " Battery 4 testing switched OFF.";
                }
                else
                {
                    Battery4[0] = "ON"; //ON or OFF
                    Battery4[1] = DateTime.Now.ToString("h:mm tt"); //Start time
                    Battery4[5] = DateTime.Now.ToString("d/MM/yyyy"); //Start date
                    plcRespond = true;
                    lblST4.Text = Battery4[1];
                        if (debug) f.DebugText = time + " Battery 4 testing switched ON.";
                }
                break;

                case "5":
                //If Battery is already on
                if (Battery5[0] == "ON")
                {
                    Battery5[0] = "OFF"; //ON or OFF
                    Battery5[2] = DateTime.Now.ToString("h:mm tt"); //End time
                    WriteLogFile("5");
                    lblST5.Text = "n/a";
                    lblET5.Text = "n/a";
                        if (debug) f.DebugText = time + " Battery 5 testing switched OFF.";
                    }
                else
                {
                    Battery5[0] = "ON"; //ON or OFF
                    Battery5[1] = DateTime.Now.ToString("h:mm tt"); //Start time
                    Battery5[5] = DateTime.Now.ToString("d/MM/yyyy"); //Start date
                    plcRespond = true;
                    lblST5.Text = Battery5[1];
                        if (debug) f.DebugText = time + " Battery 5 testing switched ON.";
                }
                break;

                case "6":
                //If Battery is already on
                if (Battery6[0] == "ON")
                {
                    Battery6[0] = "OFF"; //ON or OFF
                    Battery6[2] = DateTime.Now.ToString("h:mm tt"); //End time
                    WriteLogFile("6");
                    lblST6.Text = "n/a";
                    lblET6.Text = "n/a";
                        if (debug) f.DebugText = time + " Battery 6 testing switched OFF.";
                }
                else
                {
                    Battery6[0] = "ON"; //ON or OFF
                    Battery6[1] = DateTime.Now.ToString("h:mm tt"); //Start time
                    Battery6[5] = DateTime.Now.ToString("d/MM/yyyy"); //Start date
                    plcRespond = true;
                    lblST6.Text = Battery6[1];
                        if (debug) f.DebugText = time + " Battery 6 testing switched ON.";
                }
                break;
            }

            SerPort.DiscardInBuffer();
            SerPort.DiscardOutBuffer();

        }
        catch (Exception ex)
        {
            MessageBox.Show("Error recieving COM data! " + ex.Message);
        }
    }

有没有不使用ReadExisting读取串行数据的更好方法? 还是使用更可靠的功能?

过去,我在使用ReadExisting遇到问题。 我不知道如果在读取缓冲区时有更多数据到达,ReadExisting中会发生什么。

在串行端口甚至处理程序中,我都使用以下代码。 因为它确定了要先读取的长度,所以在下一个函数调用期间将读取新到达的数据,因此可以在发送速率数据时清空缓冲区。

private void HandleSerialData(object sender, SerialDataReceivedEventArgs e)
{
    int lengthToRead = sp.BytesToRead;
    byte[] rxBytes = new byte[lengthToRead];
    sp.Read(rxBytes, 0, lengthToRead);
    functionThatInterpratesData(rxBytes);
}

这还具有可重复使用的优点,因为您将字节数组转换为字符串,或者已对其进行单独编码。

我将创建一个函数,将您的字节数组转换为字符串(SO上的许多示例),并创建另一个函数来处理case语句。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM