我的代码旨在从串行设备获取数据,并将其内容打印到MS Forms应用程序。我使用的IDE是Visual Studio 2019 - Community。
设备确实发送了一个大小可变的数据包。首先,我必须解码数据包的“报头”,以获得进一步处理的关键信息,即第一个数据包通道和数据包长度。
由于数据包既不包含行结尾,也不包含末尾的固定字符,因此函数SerialPort.ReadTo()和SerialPort.ReadLine()没有什么用处。因此,只能使用SerialPort.Read(buf,offset,count)
由于发送相当大的数据包(512字节)确实需要时间,因此我实现了一个计算所需等待时间的函数,该函数定义为(1000ms/baud-rate*(8*byte-count))+100ms
在测试时,我遇到了延迟,远远超过了期望的等待时间,因此为函数的不同部分实现了一个度量函数。
在常规情况下(具有所需的等待时间),我在控制台上的日志除外,如下所示:Load Header(+122ms) Load Data (+326ms) Transform (+3ms)
但只有少数数量可变的记录才是这样的,通常是10条,之后,执行时间就更糟糕了:
Load Header(+972ms) Load Data (+990ms) Transform (+2ms)
在这里您可以看到完整的函数:
private void decodeWriteResponse(int identifier, object sender, SerialDataReceivedEventArgs e)
{
/* MEASURE TIME NOW */
long start = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds();
var serialPort = (SerialPort)sender; //new serial port object
int delay = ComPort.getWaitTime(7); //Returns the wait time (1s/baudrate * bytecount *8) +100ms Additional
Task.Delay(delay).Wait(); //wait until the device has send all its data!
byte[] databytes = new byte[6]; //new buffer
try
{
serialPort.Read(databytes, 0, 6); //read the data
}
catch (Exception) { };
/* MEASURE TIME NOW */
long between_header = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds();
/* Read the Data from Port */
int rec_len = databytes[1] | databytes[2] << 8; //Extract number of channels
int start_chnl = databytes[3] | databytes[4] << 8; //Extract the first channel
delay = ComPort.getWaitTime(rec_len+7); //get wait time
Task.Delay(delay).Wait(); //wait until the device has send all its data!
byte[] buf = new byte[rec_len-3]; //new buffer
try
{
serialPort.Read(buf, 0, rec_len-3); //read the data
}
catch (Exception) {}
/* MEASURE TIME NOW */
long after_load = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds();
/* Now perform spectrum analysis */
decodeSpectrumData(buf, start_chnl, rec_len-4);
/*MEASURE TIME NOW */
long end = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds();
Form.rtxtDataArea.AppendText("Load Header(+" + (between_header - start).ToString() + "ms) Load Data (+" + (after_load - between_header).ToString() + "ms) Transform (+" + (end - after_load) + "ms)\n");
/*Update the Write handler */
loadSpectrumHandler(1);
}导致此问题的原因是什么?我已经在Visual Studio中使用"debug“和"Release”独立测试了这一点,但没有区别。
发布于 2021-05-21 03:17:56
与其试图计算消息到达端口需要多长时间,为什么不直接在一个循环中读取数据,直到得到所有数据呢?例如,读取报头并计算消息大小。然后读取该字节数。例如:
// See if there are at least enough bytes for a header
if (serialPort.BytesToRead >= 6) {
byte[] databytes = new byte[6];
serialPort.Read(databytes, 0, 6);
// Parse the header - you have to create this function
int calculatedMsgSize = ValidateHeader(databytes);
byte [] msg = new byte[calculatedMsgSize];
int bytesRead = 0;
while (bytesRead < calculatedMsgSize) {
if (serialPort.BytesToRead) {
bytesRead += serialPort.Read(msg, bytesRead,
Math.min(calculatedMsgSize - bytesRead, serialPort.BytesToRead));
}
}
// You should now have a complete message
HandleMsg(msg);
}https://stackoverflow.com/questions/67626023
复制相似问题