我正在开发一个项目,我通过串口发送命令并等待响应处理。它遵循某种协议。
我面临的问题是我收到的回复是不完整的,所以我无法处理它。有些回复是在一个事件的早期发生的,其他一些事件将在之后发生。
我期待的回答如下:
05-00-0F-01-02-00-08-E2-00-60-03-11-73-D2-C1-86-5C
但我只收到05-00
,其余的都会收到,并且会不时变化,所以我无法预测。
我需要将响应存储到缓冲区,直到它完成然后处理它。我怎么能这样做?
我从串口接收的方式是这样的:
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
try
{
int ByteToRead = serialPort1.BytesToRead;
//create array to store buffer data
byte[] inputData = new byte[ByteToRead];
//read the data and store
serialPort1.Read(inputData, 0, ByteToRead);
//invoke the display in another thread
this.BeginInvoke(new DelegateDisplay(Display), new object[] { inputData });
}
catch (SystemException ex)
{
MessageBox.Show(ex.Message, "Serial Port Error ");
}
}
然后处理并显示在这里:
public void Display(byte[] inputData)
{
try
{
TboxOutput.AppendText(BitConverter.ToString(inputData, 0) + "\n");
//Add recieved data to List
List<byte> Data = new List<byte>();
try
{
for (int i = 0; i < inputData.Length; i++)
{
Data.Add(inputData[i]);
}
}
catch (SystemException ex)
{
MessageBox.Show(ex.Message + "Data Process");
}
}
catch (SystemException ex)
{
MessageBox.Show(ex.Message, "Display Error");
}
}
答案 0 :(得分:1)
这应该做:
const int timeout = 1000;
const int step = 100;
for (int t = 0; t < timeout; t += step)
{
Thread.Sleep(step);
if (serialPort1.BytesToRead >= ResponseSize)
break;
}
if (serialPort1.BytesToRead < ResponseSize)
{
serialPort1.DiscardInBuffer();
throw new Exception("Incorrect buffer size!");
}
serialPort1.Read(inputData, 0, ResponseSize);
ResponseSize
是您希望收到的消息长度。
答案 1 :(得分:0)
继续阅读,直到您有完整的回复。协议规范应指定如何判断响应是否完整。
答案 2 :(得分:0)
您可以使用列表或队列。但正如@David Schwartz所提到的,你必须找到合适的赞助人,也许是你想要阅读的链的大小,或者可能是发送者使用的协议。
这里是我用来读取的一个例子,7bit asccii。链使用格式{STX} {CHAIN} {ETX} {CRC}。但它有一个特殊情况,一个字节的答案{ACK}
从串口读取,直到得到一个完整的链,然后将该链作为字节数组返回:
public Byte[] RECIBE()
{
int count = serialPort1.BytesToRead;
if (count > 0)
{
List<Byte> bytes = new List<Byte>();
bool ETX = false;
while (ETX == false)
{
Byte b = Convert.ToByte(serialPort1.ReadByte());
if (b == 0x06)
{
bytes.Add(b);
return bytes.ToArray();
}
if (b != 0x03)
{
bytes.Add(b);
}
else
{
bytes.Add(b);
ETX = true;
}
}
Byte b2 = Convert.ToByte(serialPort1.ReadByte());
bytes.Add(b2);
return bytes.ToArray();
}
else
{
return null;
}
}