Reputation: 1977
I am trying to read data off a meter. The holy grail is 1000 samples per second
which the device actually supports. Baud rate is 38400, Parity.None
and Stopbits.One
if that matters. I am using the binary mode
to keep things as swift as possible. I plan using the DataReceived event as below.
private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
int bytesToRead = _serialPort.BytesToRead;
byte[] data = new byte[bytesToRead];
int actualBytesRead = 0;
do
{
actualBytesRead = serialPort.Read(data, 0, bytesToRead);
} while (actualBytesRead != bytesToRead);
//At this point assume that the data byte array has all the data
}
It seems that BytesToRead
will return all the bytes which are available to read for that event. However as the link says
The SerialPort class buffers data, but the stream object contained in the
SerialPort.BaseStream property does not. Therefore, the SerialPort object
and the stream object might differ on the number of bytes that are
available to read. When bytes are buffered to the SerialPort object, the
BytesToRead property includes these bytes in its value;
however, these bytes might not be accessible to the stream contained in
the BaseStream property.
And Read
returns only the number of bytes it has read.
So as a precaution against this I plan to read continually till I get the number of bytes read same as what BytesToRead indicated for the event raised. However there are few points I am not clear on.
Upvotes: 1
Views: 6031
Reputation: 61986
The following is wrong:
int actualBytesRead = 0;
do
{
actualBytesRead = serialPort.Read(data, 0, bytesToRead);
} while (actualBytesRead != bytesToRead);
In each iteration of the loop you are always passing 0 for offset
, so each time you read bytes you are overwriting bytes that were previously read.
I would rewrite it as follows:
for( int offset = 0; offset < data.Length; )
{
int n = serialPort.Read( data, offset, data.Length - offset );
offset += n;
}
Upvotes: 3