我在VisualStudio中用C#编写程序。它的基本工作方式是让我的设备以每秒250个样本(21字节数据包)进行采样,将数据中继到Teensy 3.2,然后通过USB将其中继到计算机进行处理。
我正在使用serialPort_DataReceived来确定接收数据的时间,并将ReceivedBytesThreshold设置为8.如果我正确理解这一点,每当它收到至少8个字节时,它会触发serialPort.DataReceived事件并从那里开始。但是,我的程序会发生什么,它会在收到4095个字节后触发,然后在1个字节后触发,然后在4095之后触发等。
另外,我换掉了Teensy以换取Arduino Due。在这种情况下,它会更加稳定,按照预期在每个数据包之后触发,除了在发送4095个字节后触发的奇怪的1字节数据包。如果我将设备调高到每秒8000个样本(目标速率),我会在每3个数据包之后开始获取serialPort.DataReceived。我认为是Arduino的速度减慢了,这就是为什么我切换到Teensy,因为它运行得更快。
我知道采样设备运行正常,因为我有三个并且将它们交换出来提供相同的结果,并且它们被设计为每秒处理多达16000个样本。同样,我使用Realterm来查看传入的数据流,它似乎是常量,而不是块,所以我在我的代码中找到它的东西。相关位在下面。
public Form1()
{
InitializeComponent();
serialPort1.PortName = "COM13";
serialPort1.BaudRate = 115200;
serialPort1.DataBits = 8;
serialPort1.ReceivedBytesThreshold = 21;
serialPort1.RtsEnable = true;
serialPort1.DtrEnable = true;
serialPort1.Handshake = System.IO.Ports.Handshake.XOnXOff;
}
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
byte[] buffer = new byte[serialPort1.ReadBufferSize];
int bytesRead = serialPort1.Read(buffer, 0, buffer.Length);
RxString = BitConverter.ToString(buffer, 0, bytesRead);
fixedString = RxString.Replace("-", "");
file.WriteLine(fixedString);
file.WriteLine("THIS IS A TEST");
this.BeginInvoke(new EventHandler(graph));
this.BeginInvoke(new EventHandler(DisplayText));
}
以下是输出的一些图像。 Teensy:http://i.imgur.com/0qzIpaT.png 截止日期:http://i.imgur.com/5O3fpPo.png
注意这个标题是B6B0C0
答案 0 :(得分:0)
与计算机中的大多数其他硬件相比,串行端口相当慢。您不能依赖于一次性接收所有数据。 Serial确实没有'数据包的概念,或任何大于一个字节的不可分割的单位。
接收部分消息并不罕见。如您所见,数据如何分解可能会有所不同。您可以在一侧发送1000个字节,在另一侧可以发送500和500。这很正常。如果查看串行协议,许多实现分隔符(通常为0字节),字节长度是内容的一部分。这有助于用户确定整个消息的构成。
所以要把它放在一个高级别:你需要知道消息何时开始,以及它将持续多长时间。如果您没有完整的消息,则需要保存数据并等待更多,然后重复,直到您收到完整的消息。您不能指望将字符串转换为字节的结果,并期望它完整并且可以在另一端转换回字符串。