使用C#进行串口通信延迟

时间:2014-05-12 20:06:43

标签: c# serial-port uart

我正在尝试编写一个以115200bps读取UART数据的C#应用​​程序。数据格式为:

ID: XXX Data: XX XX XX XX XX XX XX XX
ID: XXX Data: XX XX XX XX XX XX XX XX
ID: XXX Data: XX XX XX XX XX XX XX XX

其中X代表十六进制值。

每个传输以换行符结尾(' \ n')。下面是我的C#应用​​程序的代码。它只是逐行读取数据,将ID和数据字段解析为变量,然后将数据插入到dataGridView对象中。如果表中不存在ID条目,则添加它及其数据。如果ID条目已存在(是重复),则使用新数据更新重复ID条目的现有数据。这让我可以看到列出的ID中的数据是如何变化的。

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            serialPort.PortName = "COM11";
            serialPort.BaudRate = 115200;
            serialPort.Open();
            serialPort.DiscardOutBuffer();
            serialPort.DiscardInBuffer();

        }

        private delegate void SetTextDeleg(string text);
        private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            string CAN_tx = serialPort.ReadLine();
            this.BeginInvoke(new SetTextDeleg(processCAN), new object[] { CAN_tx });
        }

        void processCAN(string CAN_tx)
        {
            CANout_txtbox.Text = CAN_tx;
            Match match = Regex.Match(CAN_tx, @"^ID:\s([A-F0-9]+)\s+Data:\s([^\r]+)", RegexOptions.IgnoreCase);
            if (!match.Success) return;
            string pid = match.Groups[1].Value.Trim();
            string data = match.Groups[2].Value.Trim();
            string raw = pid + " " + data;

            string[] row = raw.Split(' ');

            int rowIndex = -1;

            try
            {
                DataGridViewRow matchRow = dataTable.Rows
                    .Cast<DataGridViewRow>()
                    .Where(r => r.Cells["PID"].Value.ToString().Equals(match.Groups[1].Value))
                    .First();

                rowIndex = matchRow.Index;
            }
            catch { }

            if (rowIndex != -1)
            {
                dataTable.Rows[rowIndex].SetValues(row);
            }
            else
            {
                dataTable.Rows.Add(row);
            }
        }
    } 
}

程序有效,但似乎串行通信性能存在问题。当我在控制台中查看数据流时,我可以看到每秒发送数百个ID。 (ID每10,20,50,100,110毫秒重复一次,具体取决于ID)当我在C#应用程序中查看数据时,我看到每秒可能有50个ID。这导致数据发送到C#应用程序的时间与数据在C#应用程序中更新的时间之间存在巨大延迟。

有没有办法为我正在使用的COM端口设置优先级?或者这里有更深层次的问题吗?我尝试降低串行缓冲区,更改超时和触发数据接收事件所需的字节数,但没有任何影响。

我已经在Python中开始了一种新的方法,因为我能够近乎实时地显示数据,但是,我想了解我的C#应用​​程序中发生了什么,这阻碍了我需要的性能。

谢谢!

2 个答案:

答案 0 :(得分:4)

  

我看到每秒可能有50个ID。

这在物理上是不可能的,你的眼睛不足以看到那种速度的变化。你用控制台模式程序欺骗了自己,你从每行在控制台窗口滚动的速率推断出每秒数百次更改。当然,永远不要读任何一个。

当您更新网格中的行时,生理效果会停止工作。现在你正在做与电影中的电影放映机相同的事情。它以每秒24帧的速度更新帧。或者您观看节目的电视,它以每秒25或30帧的速度更新帧。您无法看到各个帧,它们的变化太快,您无法观察。虽然24 fps处于低端,但数字投影前的原始速率变得普遍,闪烁趋于明显。

人类的眼睛每秒约20次更新,更快,它变成模糊。这不是一件好事,它可以帮助广播公司和戏剧剥削者花费大量资金购买昂贵的设备,这种设备将以几分钟的速度吃掉一卷胶卷。

长话短说,你正在编写一个无法使用的程序。您的用户将查看数字突然闪烁,并很快失去兴趣。将数据的火炬变成有用的信息是你必须要考虑的事情,在这里没有任何明显的想法。

答案 1 :(得分:1)

这可以通过使用background workers处理数据来解决,而主要用于执行datagrid [GUI]更新?它可能只是我,但我的大部分数据处理现在都存在于bw-ers中..

编辑:另一个想法,取决于有多少&#34;行&#34;您期望的数据,一个想法可能是将信息存储在哈希表(非常快速搜索)或数据表? &#34;延迟&#34;添加更多元素会变得更糟,是累积的​​吗?

Edit2:A good tutorial on how to correctly use background workers [你决定使用它们吗!]