收到的串行端口数据比处理的更快

时间:2014-08-19 15:19:55

标签: c# datagridview datatable serial-port invoke

我有一个波特率为115200的串口,来自arduino到我的C#Winform。我有一个数据接收事件,它调用一个新线程将传入数据添加到数据表中。数据表绑定到datagridview。我注意到的问题是,串行端口接收数据和使用新数据更新datagridview之间的延迟越来越大。我已经使用串行监视器测试了传入的数据并且没有延迟,所以问题出在我的C#代码中。下面代码中最新按钮的目的是仅保留最新的传入消息ID,并从datagridview中删除具有相同ID的旧消息。这是我的第一个C#项目,我之前从未使用过串口。

private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
    try
    {
        this.BeginInvoke(new EventHandler(DoUpdate));
    }
    catch (System.TimeoutException)
    {
    }
}

private void DoUpdate(object s, EventArgs e)
{
    string inData = serialPort1.ReadLine();
    if (dtFromGrid == null)
    {
        dtFromGrid = new DataTable();
        dtFromGrid.Columns.Add("Time", typeof(String));
        dtFromGrid.Columns.Add("ID", typeof(String));
        dtFromGrid.Columns.Add("Name", typeof(String));
        dtFromGrid.Columns.Add("Data", typeof(String));
    }

    DataRow dr = dtFromGrid.NewRow();
    TimeSpan ts = stopWatch.Elapsed;
    dr["Time"] = String.Format("{0:00}:{1:00}:{2:00}.{3:000}",
    ts.Hours, ts.Minutes, ts.Seconds,
    ts.Milliseconds);
    dr["ID"] = inData.Split(new char[] { '<', ',' })[1];
    dr["Name"] = inData.Split(new char[] { ',', '/' })[1];
    dr["Data"] = inData.Split(new char[] { '/', '>' })[1];
    dtFromGrid.Rows.InsertAt(dr, 0);

    if (NewestButton.Text == "Chronological")
    {
        for (int i = 1; i < dataGridView1.Rows.Count; i++)
        {
            if (dtFromGrid.Rows[i].ItemArray[1].ToString() == dtFromGrid.Rows[0].ItemArray[1].ToString())
            {
                dtFromGrid.Rows[i].Delete();
                break;
            }
        }
    }
    if (dtFromGrid.Rows.Count == 51)
    {
        dtFromGrid.Rows[50].Delete();
    }
    dtFromGrid.AcceptChanges();
    dataGridView1.DataSource = dtFromGrid;
    dataGridView1.CurrentCell = dataGridView1.Rows[0].Cells[0];

    if (logFile != "")
    {
        using (StreamWriter sw = File.AppendText(logFile))
        {
            DataRow row = dtFromGrid.Rows[0];
            object[] array = row.ItemArray;
            int col = 0;
            for (col = 0; col < array.Length - 1; col++)
            {
                sw.Write(array[col].ToString() + "\t|\t");
            }
            sw.Write(array[col].ToString());
            sw.WriteLine();
            sw.Close();
        }
    }
}

1 个答案:

答案 0 :(得分:0)

我认为在Arduino和C#/ .NET程序之间建立串行连接的最简单方法是使用CmdMessenger库。用法非常简单,网上有几个examples and documentation资源。

CmdMessenger在线程中使用具有处理策略的命令队列,因此您应该没有性能问题。