Main Site Documentation

Processing data of serial port


#1

From docs it is easy to read byte of serial port.
But what I would now is accumulated byte (they are char really) in buffer and process this buffer when some pattern are found.
But I don’t know how to start:

  • is it a buffer class in tinyclr ?
  • process will be launch at each byte, but is it efficient ?

All tips, block of code are welcome !!! :blush:


#2

I use a queue


#3

So this is method that I am using currently.

 private static void ReadComData() {
  Queue _streamBuffer = new Queue();
  uint _expectedBufferLength = 0;
  while (true) {
   if (comPort.BytesToRead > 0) {
	byte[] _byteBuffer = new byte[comPort.BytesToRead];
	comPort.Read(_byteBuffer, 0, _byteBuffer.Length);
	foreach(byte _b in _byteBuffer) {
	 _streamBuffer.Enqueue(_b);
	}
   }
   if (_streamBuffer.Count > 0 && _expectedBufferLength == 0) {
	while ((byte) _streamBuffer.Peek() != 0x79) { //start of frame identifier
	 _streamBuffer.Dequeue();
	}
   }
   if (_streamBuffer.Count > 3 && _expectedBufferLength == 0) {
	if ((byte) _streamBuffer.Peek() == 0x79) { //start of frame identifier
	 _streamBuffer.Dequeue();
	 _expectedBufferLength = ((uint)((byte) _streamBuffer.Dequeue() << 8) | (byte) _streamBuffer.Dequeue());
	}
   }
   if (_expectedBufferLength > 0 && _streamBuffer.Count >= (_expectedBufferLength + 1)) {
	byte _checkSum = 0;
	byte _payload = 0;
	MemoryStream _memoryStream = new MemoryStream();
	for (int i = 0; i < _expectedBufferLength; i++) {
	 _payload = (byte) _streamBuffer.Dequeue();
	 _checkSum += _payload;
	 _memoryStream.WriteByte(_payload);
	}
	_checkSum += (byte) _streamBuffer.Dequeue(); //checksum byte
	_expectedBufferLength = 0;
	if (_checkSum != 0xFF) {
	 Debug.Print("Invalid frame received. Frame discarded");
	} else {
	 XmlDocument _frame = new XmlDocument();
	 _memoryStream.Seek(0, SeekOrigin.Begin);
	 _frame.Load(_memoryStream);
	 PacketReceive(_frame);
	}
   }
   if (ResponseQueue != null && ResponseQueue.Count > 0) {
	byte[] _data = ((APIFrame) ResponseQueue.Dequeue()).ByteArray;
	comPort.Write(_data, 0, _data.Length);
	comPort.Flush();
   }
   Thread.Sleep(0);
  }
 }

#4

And here is a basic flow chart of the concept. Additionally, after you pop the length bytes, you would normally wait until the buffer had the number of bytes as specified by 2 length bytes before you withdraw them into some data structure or for further processing.


#5

Code and flow chart: very great source to begin on a sure way !

A lot of thanks. :smiley: