简体   繁体   English

使用C#的串行端口通信延迟

[英]Serial Port Communication Delay using C#

I am trying to write a C# application that reads UART data at 115200bps. 我正在尝试编写一个C#应用程序,该应用程序以115200bps的速度读取UART数据。 The data is in the format: 数据格式为:

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

where the X's represent hex values. X代表十六进制值。

Each transmission ends in a newline character ('\\n'). 每个传输都以换行符('\\ n')结尾。 Below is the code from my C# application. 下面是我的C#应用​​程序中的代码。 It simply reads the data line by line, parses out the ID and the Data fields into variables, then inserts the data into a dataGridView object. 它只是简单地逐行读取数据,将ID和Data字段解析为变量,然后将数据插入dataGridView对象。 If the ID entry does not exist in the table, it and its data are added. 如果表中不存在ID条目,则会添加它及其数据。 If the ID entry already exists (is a repeat), then the existing data for the repeated ID entry is updated with the new data. 如果ID条目已经存在(重复),则使用新数据更新重复ID条目的现有数据。 This lets me see how the data in the listed ID's are changing. 这让我看到列出的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);
            }
        }
    } 
}

The program works, however, it seems that there is a problem with the serial communication performance. 该程序可以工作,但是串行通信性能似乎有问题。 When I view the data stream in a console, i can see several hundred ID's being sent per second. 当我在控制台中查看数据流时,我可以看到每秒发送数百个ID。 (The ID's repeat every 10, 20, 50, 100, 110 ms, depending on the ID) When I view the data in the C# application, I see maybe 50 ID's per second. (根据ID,ID每10、20、50、100、110毫秒重复一次)当我在C#应用程序中查看数据时,每秒可能看到50个ID。 This results in a huge delay between the time the data is sent to the C# application and the time the data is updated in the C# application. 这导致将数据发送到C#应用程序的时间与在C#应用程序中更新数据的时间之间的巨大延迟。

Is there some way to set priority to the COM port I am using? 有什么方法可以设置我正在使用的COM端口的优先级? Or is there deeper issues here? 还是这里有更深层次的问题? I tried lowering the serial buffer, changing timeouts, and number of bytes needed to trigger the data received event, but nothing has made an impact. 我尝试降低串行缓冲区,更改超时和触发数据接收事件所需的字节数,但没有任何影响。

I have already started a new approach in Python as I was able to display data in near real time, however, I would like to understand what is happening in my C# application that is preventing the performance I need. 我已经在Python中启动了一种新方法,因为我能够近乎实时地显示数据,但是,我想了解C#应用程序中正在发生的妨碍我所需性能的事情。

Thanks! 谢谢!

I see maybe 50 ID's per second. 我看到每秒可能有50个ID。

That's not physically possible, your eyes are not good enough to see changes at that rate. 这在身体上是不可能的,您的眼睛还不够好,无法以这种速度看到变化。 You fooled yourself with the console mode program, you inferred hundreds of changes per second from the rate at which the lines scrolled across the console window. 您以控制台模式程序自欺欺人,从每秒在控制台窗口中滚动的速度推断出每秒数百次更改。 Never actually reading any of them of course. 当然,从不真正阅读其中任何一个。

That physiological effect stops working when you update rows in the grid. 当您更新网格中的行时,这种生理效果将停止工作。 Now you are doing the same thing that the movie projector in the cinema does. 现在,您正在做与电影院中的电影放映机相同的操作。 It updates frames at 24 per second. 它以每秒24个的速度更新帧。 Or the television you watched a show on, it updates frames at 25 or 30 per second. 或您观看过电视节目的电视,它以每秒25或30的速度更新帧。 You cannot see the individual frames, they change too fast for your eye to observe. 您看不到各个帧,它们变化太快,以至于您的眼睛无法观察到。 Albeit that 24 fps is on the low end, the original rate before digital projection became common, the flicker tended to be noticeable. 尽管24 fps是低端,但在数字投影变得普遍之前的原始速率下,闪烁趋于明显。

Human eyes conk out at around 20 updates per second, go any faster and it just turns into a blur. 人眼每秒大约可听到20次更新,然后以更快的速度运转,它变得模糊起来。 Which is otherwise a Good Thing, it helps the broadcasters and theater exploiters from spending a lot of money on expensive equipment, the kind that will eat a roll of film in a manner of minutes. 否则,这是一件好事,它可以帮助广播公司和剧院开发者在昂贵的设备上花费大量金钱,而这种设备将在几分钟内吃完一卷胶卷。

Long story short, you are writing an unusable program. 长话短说,您正在编写一个无法使用的程序。 Your user will look at the wildly blinking numbers and quickly lose interest. 您的用户将看到闪烁的数字,并很快失去兴趣。 Turning the firehose of data into useful information is something you'll have to think about, nothing very obvious jumps to mind here. 将数据转换为有用的信息是您必须要考虑的事情,这里没有什么显而易见的想法。

This might be solved by using background workers to process the data and main just for doing datagrid [GUI] updates? 这可以通过使用后台工作人员处理数据来解决,而主要是为了进行数据网格[GUI]更新? It could be just me, but the majority of my data processing lives in bw-ers these days.. 可能只有我一个人,但是这些天我的大部分数据处理都生活在仓库中。

Edit: Another thought, depending on how many "rows" of data your are expecting, an idea might be to store the info in a hashtable (very fast to search) or datatable? 编辑:另一种想法,取决于您期望的数据“行”数,一个想法可能是将信息存储在哈希表(搜索速度非常快)或数据表中? Does the "delay" get worse when more elements are added, is it cumulative? 当添加更多元素时,“延迟”会变差吗,它是累积的吗?

Edit2: A good tutorial on how to correctly use background workers [Should you decide to use them!] Edit2: 关于如何正确使用后台工作程序的很好的教程 [您应该决定使用它们!]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM