0

我正在尝试放置一个 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
    }
4

3 回答 3

0

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

于 2013-11-07T02:24:59.913 回答
0

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

因为 port_DataReceived 会在收到数据时触发,所以不应该放入getDataPointport.Open();方法

于 2013-11-07T02:36:39.040 回答
0

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

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

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

于 2013-11-15T17:32:08.230 回答