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

时间:2017-07-04 08:47:14

标签: c# serialization

我使用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;
    }

My Recieve事件功能:

    //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的串行数据?或者使用更可靠的功能?

1 个答案:

答案 0 :(得分:1)

过去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语句。