我正在尝试编写一个以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#应用程序中发生了什么,这阻碍了我需要的性能。
谢谢!
答案 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 [你决定使用它们吗!]