UART buffer size

@ Gralin: can you join the chat? don’t want to mess up this thread :slight_smile:

Oh now I see that Gralin uses the _serialPort.DataReceived event. I would not do that. I think a polling thread causes less overhead and will react faster to incomming data, no?

Those return statements are ok if used as event handler. But the while (data available) will block if data keeps comming in…

I’m studying @ Wouter Huysentruit code (because is the first I’ve seen) and I’ve some questions:
ACCEPTABLE is the minimum size a frame can have? I think so…

ProcessPacket(buffer, bytesInBuffer, out bytesConsumed);

buffer -> contains data.
bytesInBuffer -> contains amount of datas
bytesConsumed -> What is this?

Mi frames are so:
02LLXXXX…XXXCC
Where 02 is bytestart
LL is the length of the frame
And CC is the checksum

I’ve seen that buffer contains all frames I send. So I think ProcessPacket is who have to check lenght, checksum and split every frame, doesn’t it?

Thanks for your help!!

is bytestart and checksum included in the length byte?

Improved version (first version will not work reliable)


private void ReceiveData()
{
	byte[] buffer = new byte[1024];	// Make sure this buffer is large enough to hold a full packet
	int bytesInBuffer = 0;
 
	_serialPort = new SerialPort(_port, _baudRate);
	_serialPort.Open();
 
	while (!_stopThd)
	{
		while (_serialPort.BytesToRead > 0)
		{
			int bytesRead = _serialPort.Read(buffer, bytesInBuffer, buffer.Length - bytesInBuffer);
 
			if (bytesRead <= 0)
				break;

			// Update number of bytes in buffer
			bytesInBuffer += bytesRead;

			// As long as we find a PACKET_STARTBYTE in the buffer...
			while ((startOfPacket = Array.IndexOf(buffer, EpiZBResponse.PACKET_STARTBYTE, 0, bytesInBuffer)) >= 0)
			{
				// Throw away bytes before PACKET_STARTBYTE
				if (startOfPacket > 0)
				{
					bytesInBuffer -= startOfPacket;
					if (bytesInBuffer > 0)
						Array.Copy(buffer, startOfPacket, buffer, 0, bytesInBuffer);
					else
						bytesInBuffer = 0;
				}

				// We must have at least 3 bytes to have a valid packet (START, LENGTH and CHECKSUM byte)
				if (bytesInBuffer < 3)
					break;

				// buffer[0] = STARTBYTE
				// buffer[1] = LENGTH
				// buffer[x] = CHECKSUM
				// ProcessPacket returns the number of bytes that were used by the packet (so including startbyte, length, data and checksum)
				int bytesConsumed = ProcessPacket(buffer, bytesInBuffer);

				// If ProcessPacket could not find a packet (f.e. incorrect checksum...) it can return 0.
				// In that case we set bytesConsumed to 1 so at least the first byte (PACKET_STARTBYTE) is removed from the buffer
				// before we do further analysis
				if (bytesConsumed <= 0)
					bytesConsumed = 1;

				// Throw away bytes consumed by the ProcessPacket method
				bytesInBuffer -= bytesConsumed;
				if (bytesInBuffer > 0)
					Array.Copy(buffer, bytesConsumed, buffer, 0, bytesInBuffer);
				else
					bytesInBuffer = 0;
			}
		}
 
		Thread.Sleep(20);
	}
 
	_serialPort.Close();
}

@ Wouter I’m glad we cleared things out. I didn’t compare the speed of pooling vs event in case of serial port. Events might be better if data comes at random and pooling if there is constant load of data…

In length are excluded StartOfFrame byte, Length and Checksum.

The key is that frames can have different size, always with at less 24 bytes.

Data comes random (they come from some devices, all sending data at the same time). Once I have a right frame I return it to the main and, in other thread, I process it :wink: