我正在编写一个应用程序,通过串行连接从远程无线电接收一些输入。我目前正在使用SerialPort C#类来接收和发送数据,但我遇到了一些问题。我注意到我接收数据的功能没有正确设置缓冲区字节数组大小。所有数据都以字节码(十六进制)发送。
假设另一个节点发送103个字节的数据。单步执行我的代码并在“Read()”行设置断点,我看到“serialPort1.BytesToRead-1”的计算结果为103,但是byte []数组仅初始化为17.我没有解释这种行为。结果,只有前17个字节被放入数组中。继续执行该步骤,触发同一事件,这次“serialPort1.BytesToRead-1”评估为85(可能是因为只读取了103个字节中的前17个。
如果我将数据阵列大小硬核为103,那么它可以在一次通过中完美运行。但是,目前我无法在一次传递中将所有数据存储在我的字节数组中,这导致了很多问题。任何人都知道为什么我的字节数组被初始化为这样一个任意大小???
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
byte[] data = new byte[serialPort1.BytesToRead - 1];
serialPort1.Read(data, 0, data.Length);
DisplayData(ByteToHex(data) /*+ "\n"*/);
}
更新:这是我正在尝试的新方法。 isHeader是一个初始设置为true的布尔值(因为从数据包接收的前两个字节实际上是数据包的长度)。
const int NUM_HEADER_BYTES = 2;
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
byte[] headerdata = new byte[2];
if (isHeader)
{
serialPort1.Read(headerdata, 0, NUM_HEADER_BYTES);
int totalSize = (headerdata[0] << 8 | headerdata[1]) >> 6;
serialPort1.ReceivedBytesThreshold = totalSize - NUM_HEADER_BYTES;
data = new byte[totalSize - NUM_HEADER_BYTES];
isHeader = false;
}
else
{
serialPort1.Read(data, 0, data.Length);
double[][] results = ParseData(data, data.Length);
serialPort1.ReceivedBytesThreshold = NUM_HEADER_BYTES;
isHeader = true;
DisplayData(ByteToHex(data) /*+ "\n"*/);
}
}
答案 0 :(得分:3)
BytesToRead等于缓冲区中等待的字节数。随着新数据的到来,它会随时变化,这就是你在这里看到的。
当您使用调试器时,需要额外的时间,并且当您踩入调试器时,其余的串行数据会进入,因此BytesToRead会更改为完整值104.
如果您知道需要103个字节,我相信将ReceivedBytesThreshold设置为104将在适当的时间触发DataRecieved事件。如果您不知道需要接收的邮件大小,则需要执行其他操作。我注意到你扔掉了一个字节(serialPort1.BytesToRead - 1 ),这是你在读取数据时可以搜索的消息结束字节吗?
答案 1 :(得分:2)
在实时数据传输方面,调试器无法提供。使用调试跟踪。
BTW我自己会使用轮询数据,而不是信任事件。使用串行端口,这是一种合理可靠的方法。修改每条评论: 串行数据传输速率受波特率的限制。 你担心丢失数据,所以让我们看看数字:
假设:
baud_rate = 19600 [bytes/sec] // it's usually *bits*, but we want to err upwards
buffer_size = 4096 [bytes] // windows allocated default buffer size
所以需要:
4096/19600 [sec] ~ 200 [ms]
溢出缓冲区(上限)。
因此,如果您在50 Hz
进行采样,那么您将运行一个数量级的安全网,这是一个很好的选择。在每个'样本'上,您阅读整个缓冲区。这里没有时间问题。
当然你应该对你的情况采用这些数字,但是如果你的低带宽RF信道将导致50 Hz
不足以成为过度的传输速率,我会感到惊讶。
最后编辑: 毋庸置疑,如果您目前拥有的作品,那么就不会触摸它。