I’m trying to receive serial data at a baudrate of 19200 (1 stopbit, no parity, RTS-CTS handshaking).
The problem is that the FEZ frequently drops one or more incomming bytes.
In short, this is what my code should does:
send a code to request a table (= 3 bytes)
receive the table byte by byte and verify sync and crc ccitt at the end.
In my first tryout I called SerialPort.Read for each byte. I thought this was the problem of the dropped bytes (maybe the FEZ couldn’t follow).
So I created a thread that always receives as much data as possible.
Some declarations:
private byte[] inputBuffer = new byte[1024];
private int inputBufferUsed = 0;
private int readTimeout = 5000;
private ManualResetEvent dataReceived = new ManualResetEvent(false);
This is the thread function:
private void SerialThreadProc()
{
byte[] buffer = new byte[1];
while (!terminate)
{
int inputBufferFree = inputBuffer.Length - inputBufferUsed;
if (inputBufferFree > 0)
{
if (serialPort.Read(buffer, 0, 1) == 1)
{
lock (inputBuffer)
{
inputBuffer[inputBufferUsed++] = buffer[0];
dataReceived.Set();
}
}
}
else
Thread.Sleep(100); // Buffer full
}
}
This is how I receive a byte:
public bool WaitByte(out byte data)
{
bool mustWait = false;
data = 0;
try
{
lock (inputBuffer)
{
if (inputBufferUsed > 0)
{
data = inputBuffer[0];
inputBufferUsed--;
Array.Copy(inputBuffer, 1, inputBuffer, 0, inputBufferUsed);
return true;
}
else
{
dataReceived.Reset();
mustWait = true;
}
}
if (mustWait && dataReceived.WaitOne(readTimeout, false))
{
lock (inputBuffer)
{
data = inputBuffer[0];
inputBufferUsed--;
Array.Copy(inputBuffer, 1, inputBuffer, 0, inputBufferUsed);
return true;
}
}
}
catch (Exception e)
{
client.OnError(Client.ErrorCause.SerialReadWriteError, e.Message);
}
return false;
}
What I have now is lost bytes but my inputBuffer never gets completly full, so:
- the ‘lost’ bytes never get in
- the serialport stops working
Is there something else I should try?