I am working on a project where i send a command through serial port and wait for the response to process. it follows some kind of protocol.
the problem i am facing is the response i am receiving is incomplete, so i am unable to process it. Some the response comes early at one event and some others will follow afterwards.
the response i am expecting looks like this:
05-00-0F-01-02-00-08-E2-00-60-03-11-73-D2-C1-86-5C
but i will receive only 05-00
and the rest comes after and it changes from time to time, so i can't predict.
i need to store the response to a buffer until it is complete then process it. how can i do that?
the way i am receiving from serial port is like this:
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 ");
}
}
then process and display at here:
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");
}
}
This should do:
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);
Where ResponseSize
is the length of message you expect to recieve.
Keep reading until you have the complete response. The protocol specification should specify how you tell if the response is complete.
you could use lists, or queues. but as @David Schwartz mentioned, you have to figure the right patron, maybe the size of the chain you're trying to read, or maybe the protocol being used for the sender.
here an example I use to read, 7bit asccii. the chains usin format {STX}{CHAIN}{ETX}{CRC}. But it have a particular case, with an one byte answer {ACK}
this reads from serial port, till get a complete chain, and returns that chain as a byte array:
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;
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.