C#表示"端口已经打开。"修复它,然后"端口关闭。"我的代码出了什么问题?

时间:2013-11-07 02:18:24

标签: c# .net serial-port

我正在尝试使用Serial DataReceivedListener来自动从串行端口读取数据。在添加此活动之前,一切正常。

某些命令无法继续,因为C#抱怨“端口已经打开”。如果我注释掉“port.Open();”,那么C#会抱怨“端口已关闭。”

以下是我认为完整的代码。

    SerialPort port;

    String buffer;
    String[] bufferArray;
    String tellArduino;   // any random one-byte character to "ping" Arduino for a data point

    Queue<String> date = new Queue<String>();
    Queue<String> time = new Queue<String>();
    Queue<double> dcGen = new Queue<double>();


public Form1()
    {
        //
        //  IDE created this thing
        //
        InitializeComponent();
    }

    void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        getDataPoint();
    }

    private void selectPort()
    {
        //
        //  Creates new instance of SerialPort with the same
        //  settings as that of the Arduino. Checks if the selected
        //  port can be opened. Catches common exceptions found while debugging
        //

        try
        {
            port = new SerialPort((string)ports.SelectedItem);
            port.BaudRate = 9600;
            port.Parity = Parity.None;
            port.StopBits = StopBits.One;


            port.Open();        // check if port can be opened
            port.Close();

            portUsedLabel.Text = (string)ports.SelectedItem;

            port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);

            getDataPoint();    // called here for testing. Values successfully split
        }
        // gotta catch 'em all
        catch { stuff here }
    }

    private void getDataPoint()
    {
        /* still incomplete due to debugging phase */

        //
        //  Method for getting a data point from the Arduino unit
        //  Pings Arduino unit for a data point. Program then reads
        //  entire serial output until new line (\n) is found.
        //  Program splits the entire buffer in to the bufferArray
        //  and proceeds to distribute each element in to their
        //  respective Queues
        //

        buffer = "";
        bufferArray = new String[] { "" };
        tellArduino = "m";    // any random one-byte string to "ping" Arduino for a data point
                              // it |must| remain exactly one byte to avoid duplicate data

        port.Open();
        port.WriteLine(tellArduino);

        for (int x = 0; x < tellArduino.Length; x++)
        {
            buffer += port.ReadLine();
        }
        port.Close();

        // Split each value then add to respective queues
        bufferArray = buffer.Split(',');

        date.Enqueue(bufferArray[0]);
        time.Enqueue(bufferArray[1]);
        dcGen.Enqueue(double.Parse(bufferArray[2], System.Globalization.CultureInfo.InvariantCulture));


        // Start debugging code
        // adding to ListBox for debugging and checking reasons
        ports.BeginUpdate();
        foreach (String value in bufferArray)
        {
            ports.Items.Add(value);
        }
        // for testing type double printing
        ports.Items.Add(dcGen.ElementAt(0));
        //

        ports.EndUpdate();
        // End debugging code
    }

3 个答案:

答案 0 :(得分:0)

您可能会同时执行getDataPoint()。 DataReceived将触发你的getDataPoint(),然后你打开和关闭端口。只需在选择端口打开端口一次,然后在退出程序时关闭它或单击“断开连接”。

答案 1 :(得分:0)

我认为您应该尝试在方法 selectPort 中选择端口时打开一次端口,并在关闭应用程序时关闭端口一次(窗体关闭事件)。

因为port_DataReceived会在接收数据时触发,因此您不应将port.Open();放入方法 getDataPoint。

答案 2 :(得分:0)

我总是在实例化或打开任何串口之前立即插入此代码。它也在我的Form_Closing事件处理程序中。

if ((m_SerialPort != null)) {
    if (m_SerialPort.IsOpen) {
        m_SerialPort.Close();
    }
}

如果您必须在端口打开时停止调试程序,这一点尤其重要。