【发布时间】:2020-02-18 15:12:35
【问题描述】:
我对所有这些 C# 东西都很陌生,更习惯于嵌入式 C。 我正在尝试开发一个 Windows 表单记录器来执行以下操作:-
以状态帧 14 字节的形式从端口接收串行数据,通常在记录开始前几秒钟。然后以每秒 2000 次 (52kbytes/s) 的速率发送 26 字节数据帧
需要对帧进行解码、检查是否有效、提取样本计数器并从帧中提取四个 8 位 ADC 通道以在记录停止后导出到 csv。
在 GUI 中绘制一个 ADC 通道。
我正在使用以下方法:
- 使用
serialPort1_DataReceived事件读取rx data。 - 此事件还调用解码函数,将解码后的数据添加到 结构列表
- GUI 有一个计时器,可以从结构列表中读取数据以进行绘图 图表。
- ADC 通道为 10ksps,因此每 10 个样本绘制一次(1ksps 显示)
我希望看到绘制的测试信号的分辨率降低,但缺少部分。
看起来程序在解码和显示其数据接收事件时正在丢弃字节。有更好的方法吗?
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
int num_bytes;
byte[] ecu_status = new byte[140];
num_bytes = serialPort1.BytesToRead;
// Console.WriteLine(num_bytes);
// status frames muliples of 14 bytes
if (num_bytes % 14 == 0 && num_bytes < 140 && _start_log_flag == false)
{
serialPort1.Read(ecu_status, 0, num_bytes);
decode_status(ecu_status, num_bytes);
}
else if (num_bytes > 25) // data frames 26 bytes
{
byte[] ecu_data = new byte[num_bytes];
serialPort1.Read(ecu_data, 0, num_bytes);
decode_data(ecu_data, num_bytes);
_start_log_flag = true;
}
else serialPort1.DiscardInBuffer(); // corupt clear buffer
}
我已将上述事件更新为下面的事件,它有所改进,但我仍然每 1 秒或 10,000 个样本出现故障/轻微丢失数据?
private void sp_DataReceived(object sender, SerialDataReceivedEventArgs e) // Receive data event callback
{
//stopwatch.Stop(); // Stop timing.
// Console.WriteLine("Time elapsed: {0}", stopwatch.Elapsed); // Write result.
int no_bytes;
no_bytes = sp.BytesToRead; // get num bytes from serial port buffer
if ((no_bytes == 14 || no_bytes == 28) && !_start_log_flag) // check if status frame\s (14 bytes each) once logging ignore status frames
{
byte[] _rx_data = new byte[no_bytes]; // create array for data
sp.Read(_rx_data, 0, no_bytes); // get status frame\s from serial buffer
decode_status(_rx_data, no_bytes); // decode & process status frame\s
}
else if ((no_bytes == 26 || (no_bytes > 51 && no_bytes < 4097)) && _live_stream) // check for data frames (26 bytes each)
{
_start_log_flag = true; // now logging
Console.WriteLine(no_bytes);
byte[] _rx_data1 = new byte[no_bytes]; // create array for data
sp.Read(_rx_data1, 0, no_bytes); // get data frames from comms buffer
data_frames.Enqueue(_rx_data1); // queue array to process later
}
else
{
sp.DiscardInBuffer(); // jibberish clear buffer
}
// stopwatch.Reset();
// stopwatch.Start();
}
【问题讨论】:
-
欢迎来到 SO。请阅读How to Ask、tour 和minimal reproducible example 以改进您的问题
-
我的猜测是你在事件中读取数据错误并且没有完全读取缓冲区中的每个字节,但是没有代码很难说你做错了什么。
-
c# 是最好的方法吗?开销可能会影响数据。
-
你能添加你的
serialPort1_DataReceived事件代码吗? -
这不是一个论坛,它是一个问答网站。请编辑您的问题以包含此信息,然后删除此答案 - Scott Chamberlain 17 小时前
标签: c# winforms logging serial-port decode