为什么 SerialDataReceivedEventArgs 收到不完整的数据?
Why SerialDataReceivedEventArgs receive incomplete data?
我目前正在研究 IO 板。串行对象已初始化并侦听传入数据。我正在使用 SerialPort1.ReadExisting();
读取传入数据作为传入字符串,预计在每次读取时都会以 {X000000}5E + \r\n
形式到达。
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
try
{
TextBox2.Invoke(new EventHandler(delegate
{
TextBox2.AppendText(SerialPort1.ReadExisting());
}));
}
catch
{
MessageBox.Show("Couldn't open Port", "Error");
}
}
当像那样使用 ReadExisting() 时,我得到了我想要的结果,我会得到介于“{X”和“}”之间的值,但是当我做一个 split char 时,我总是出错关于索引超出范围。我改变了读取方式,在读取的时候加上Environment.NewLine
来判断数据是否接收完整。结果将如下图所示。
我也根据 SO 答案尝试如下所示,但传入的字符串数据将与上图相同:-
var end = '\r';
int dataLength = _serialPort.BytesToRead;
byte[] data = new byte[dataLength];
int nbrDataRead = _serialPort.Read(data, 0, dataLength);
string RxString = System.Text.Encoding.ASCII.GetString(data);
LogEvents($"Serial port data: {RxString}");
It's like the full set of {X000000}5E is coming in 1-3 times in split to SerialDataReceivedEventArgs
.
我读错了吗?我还将波特率从 9600 增加到 19200,但传入的数据仍然与提供的图像相同。跟IO板程序有关系吗?我不太确定。
正如@jdweng 所指出的,串行端口 DataReceived
事件有点随机触发。它可能会触发中间字符串,您只能收到一半的消息。您必须构建自己的字符串。大多数串行到串行通信使用回车 returns (\r
) 或换行符 (\n
) 来确定消息已完成。根据您告诉我们的内容,您似乎在末尾添加了 <CR><LF>
,因此我们可以查找 LF 以了解我们获得了整个字符串。
char LF = (char)10;
StringBuilder sb = new StringBuilder();
string currentLine = string.Empty;
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
string Data = serialPort1.ReadExisting();
foreach (char c in Data)
{
if (c == LF)
{
sb.Append(c);
CurrentLine = sb.ToString();
sb.Clear();
//parse CurrentLine here or print it to textbox
}
else
{
sb.Append(c);
}
}
}
所以在上面的例子中,我正在寻找一个换行字符来知道我收到了完整的消息。 (LF 或 \n
)。
我目前正在研究 IO 板。串行对象已初始化并侦听传入数据。我正在使用 SerialPort1.ReadExisting();
读取传入数据作为传入字符串,预计在每次读取时都会以 {X000000}5E + \r\n
形式到达。
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
try
{
TextBox2.Invoke(new EventHandler(delegate
{
TextBox2.AppendText(SerialPort1.ReadExisting());
}));
}
catch
{
MessageBox.Show("Couldn't open Port", "Error");
}
}
当像那样使用 ReadExisting() 时,我得到了我想要的结果,我会得到介于“{X”和“}”之间的值,但是当我做一个 split char 时,我总是出错关于索引超出范围。我改变了读取方式,在读取的时候加上Environment.NewLine
来判断数据是否接收完整。结果将如下图所示。
我也根据 SO 答案尝试如下所示,但传入的字符串数据将与上图相同:-
var end = '\r';
int dataLength = _serialPort.BytesToRead;
byte[] data = new byte[dataLength];
int nbrDataRead = _serialPort.Read(data, 0, dataLength);
string RxString = System.Text.Encoding.ASCII.GetString(data);
LogEvents($"Serial port data: {RxString}");
It's like the full set of {X000000}5E is coming in 1-3 times in split to
SerialDataReceivedEventArgs
.
我读错了吗?我还将波特率从 9600 增加到 19200,但传入的数据仍然与提供的图像相同。跟IO板程序有关系吗?我不太确定。
正如@jdweng 所指出的,串行端口 DataReceived
事件有点随机触发。它可能会触发中间字符串,您只能收到一半的消息。您必须构建自己的字符串。大多数串行到串行通信使用回车 returns (\r
) 或换行符 (\n
) 来确定消息已完成。根据您告诉我们的内容,您似乎在末尾添加了 <CR><LF>
,因此我们可以查找 LF 以了解我们获得了整个字符串。
char LF = (char)10;
StringBuilder sb = new StringBuilder();
string currentLine = string.Empty;
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
string Data = serialPort1.ReadExisting();
foreach (char c in Data)
{
if (c == LF)
{
sb.Append(c);
CurrentLine = sb.ToString();
sb.Clear();
//parse CurrentLine here or print it to textbox
}
else
{
sb.Append(c);
}
}
}
所以在上面的例子中,我正在寻找一个换行字符来知道我收到了完整的消息。 (LF 或 \n
)。