如何解决C#串口通信高速通信时丢失字节
我用 C# 创建了一个程序来接收来自我的 Teensy 4.1 uController 的高速数据。控制器只是每 1 微秒测量两个通道的电压,并通过 USB 将它们与时间戳一起发送。每次读取的数据包长度为 18 字节:4 字节(前导码)+ 1 字节(数据包长度)+ 1 字节(测量类型)+ 12 字节(所有信息:4 字节(时间戳)、4 字节(电压1)、 4 个字节(电压 2)。)。因此,我通过 USB 端口获得了 18 MBps。 Teensy 以 USB 2.0 的速度工作,因此限制为 480 Mbps / 8 = 60 MBps-所以这不是问题。
就目前而言,我只发送短时间的数据,比如 1 秒。
在我的 C# 程序中,我有两种方法来显示这些数据:实时处理和被动模式。
我已经分离了串口中断,从那以后丢失的数据要高得多。
我尝试了双缓冲技术,但仍然缺少数据。
我想解决这个丢失数据的问题。任何帮助将不胜感激。
我的代码是:
// Global variables
int passiveMode = 0;
int serialReadFlag = 0;
BlockingCollection<byte> fifo_queue = null;
int TEENSYADC = 40;
int PREAMBLE = 85;
int PREAMBLE_COUNT=4;
//
private void requestResponse()
{
serialReadFlag = 1;
serialPortTeensy.DataReceived -= new SerialDataReceivedEventHandler(this.serialPortTeensy_DataReceived);
serialPortTeensy.discardInBuffer();
serialPortTeensy.discardOutBuffer();
fifo_queue = new BlockingCollection<byte>();
serialPortTeensy.WriteLine(RESPONSE + 1); //Request response from Teensy
passiveMode = 0; // change to 1 to enable passive mode
if (passiveMode == 0)
{
Thread readThread = new Thread(readTSnewDouble);
readThread.Priority = ThreadPriority.Highest;
readThread.Start();
Thread processthread = new Thread(processtSnewDouble);
processthread.Start();
}
else
{
Thread readThread = new Thread(readTSnewfast);
readThread.Priority = ThreadPriority.Highest;
readThread.Start();
}
}
private void readTSnew()
{
while (serialReadFlag > 0 || serialPortTeensy.BytesToRead > 0) // In Passive mode,a timer interrupt method will change the serialReadFlag to 0
{
try
{
int serialbytestoread = serialPortTeensy.BytesToRead;
byte[] buffer = new byte[serialbytestoread];
serialPortTeensy.Read(buffer,buffer.Length);
lock (serialLock)
{
foreach (var b in buffer)
fifo_queue.Add(b);
}
}
catch
{
}
//Thread.Sleep(1); // If I turn this on,I miss much more data. Wanted to used this to accumulate more data in the serial buffer but then its somehow results in a loss of data.
}
if (passiveMode == 1) // Passive mode will process after full data is acquired.
{
Thread processthread = new Thread(processtSnew);
processthread.Start();
}
}
处理数据的方法
while (serialReadFlag > 0 || fifo_queue.Count > 0)
{
try
{
while (fifo_queue.Count > 0)
{
int incoming_byte = 0;
long message1 = 0;
long message2 = 0;
long message3 = 0;
if (preamble_count < PREAMBLE_COUNT)
{
incoming_byte = fifo_queue.Take();
}
if (incoming_byte == PREAMBLE && preamble_count < PREAMBLE_COUNT)
{
preamble_count++;
}
else if (fifo_queue.Count > 0 && preamble_count == PREAMBLE_COUNT)
{
int len = fifo_queue.ElementAt(0);
if (fifo_queue.Count > len - 1)
{
len = fifo_queue.Take();
int type = fifo_queue.Take();
switch (type)
{
case TEENSYADC:
if (len == 2)
{
abortReponse();
serialReadFlag = 0;
serialPortTeensy.DataReceived += new SerialDataReceivedEventHandler(this.serialPortTeensy_DataReceived);
break;
}
else
{
message1 = (long)fifo_queue.Take() << 24;
message1 |= (long)fifo_queue.Take() << 16;
message1 |= (long)fifo_queue.Take() << 8;
message1 |= (long)fifo_queue.Take();
message2 = (long)fifo_queue.Take() << 24;
message2 |= (long)fifo_queue.Take() << 16;
message2 |= (long)fifo_queue.Take() << 8;
message2 |= (long)fifo_queue.Take();
message3 = (long)fifo_queue.Take() << 24;
message3 |= (long)fifo_queue.Take() << 16;
message3 |= (long)fifo_queue.Take() << 8;
message3 |= (long)fifo_queue.Take();
servicepResponse(message1,message2,message3);
}
break;
default:
break;
}
}
preamble_count = 0;
}
else // not enough data received yet or garbage was received
{
}
}
}
catch
{ }
}
fifo_queue.dispose();
在下面的图片中,您会看到我在实时模式下遗漏了一些数据,但在被动模式下没有。但请记住,数据有时也会在被动模式下丢失,但频率较低。
plot for the data received in the real-time mode
plot for the data received in the passive mode
我最近开始用 C# 编程,但我对执行线程安全操作的了解不多。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。