When using Microsoft Visual Studio with .NET code, there are multiple ways to read data from serial ports, mainly these:
Read
SerialPort.Read(byte[] buffer, int offset, int count);
This reads until the defined buffer is full
Read Existing
SerialPort.ReadExisting();
This reads the currently existing data bytes at the serial Port
Read To
SerialPort.ReadTo(string delimter);
This reads until a defined delimiter, e.g. "\r" is found.
Problem
The issue I am currently facing, is that my device operates in two modes, in normal mode, I can send command, and a response with \n
in the end is sent, so this function can be processed with
string response = SerialPort.ReadTo("\n");
In data sending mode, the device sends data in bytes and variable package sizes, the data packets can be 5 to 1024 byte, and have no unique character at the end. In fact, the last characters are a checksum, so they will surely differ in each packet/stream. Therefore, the function
SerialPort.Read(byte[] buffer, int offset, int count);
cannot be used, since count
is unknown. Additionally, the function
SerialPort.ReadExisting();
Is of no use, since it will only read the first bytes of the packed, and not the complete data stream.
Workaround
My current workaround is the following, which has the issue that its slow, and relies on the estimation of the highest packet size of 1024. To be
private void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e)
{
Task.Delay(900).Wait() //9600baud = 1200byte/s = 1024byte/1200byte = 0.85
string response = SerialPort.readExisting();
}
The major issue with my workaround is that it has to wait the complete time, even if the device sends a small amount of bytes (e.g. 100). Additionally, if the device is switched to a higher speed (e.g. 38400baud) the wait time could be way lower.
How could I deal with this problem in a proper way?