Main Site Documentation

SerialPort via XBee Data Receiver Pattern Needed


#1

I’m looking for advice on receiving packets using the SerialPort class where the source is wireless (XBee). I’ve been playing with different techniques for the past couple weeks and still don’t have a fast & reliable solution. I’m close with the speed and I think I can work that out but my main problem now is finding a good solution for capturing messages that span multiple packets/events. Trying to do this while minimizing string copies to keep up the performance has been a challenge. This is one case where I’d love to have pointers in C#… So, if anyone has any sample code that solves this problem I’d love to see it.

Thanks!

Ian


#2

Of course, not long after posting I came up with a solution that is working fairly well. I’m still welcoming constructive criticism if anyone has any ideas for further optimization. I need this to work as quickly as possible.


        private static string _lastCommand;
        public DataReceiver DataProcessor;
        private static string _commandBuffer;
        private void OnDataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            var received = _commandBuffer;
            //while (true)
            //{
            // Read all data and buffer to a string.
            var bytesReceived = ((SerialPort) sender).BytesToRead;
            var bytes = new byte[bytesReceived];
            ((SerialPort) sender).Read(bytes, 0, bytesReceived);
            received += new string(Encoding.UTF8.GetChars(bytes));
            // Make sure there is a command prefix.
            var prefixNdx = received.IndexOf(COMMAND_PREFIX);
            if (prefixNdx < 0) return;      // No valid command prefix exists.
            // If there is not also a suffix then carry the received data over to the next packet.
            var suffixNdx = received.IndexOf(COMMAND_SUFFIX);
            if (suffixNdx < 0)
            {
                _commandBuffer = received;
                return;
            }
            var command = "";
            for(var ndx = prefixNdx; ndx < received.Length; ndx++)
            {
                var c = received[ndx];
                if (c == COMMAND_SUFFIX)
                {
                    if(command != "" && command != _lastCommand) ProcessCommand(command);
                    command = "";
                }
                else if (c != COMMAND_PREFIX) command += c;
            }
            _commandBuffer = command;
        }

The data I’m currently sending is in the following format where

[ is the COMMAND_PREFIX
| is the COMMAND_DELIMITER
] is the COMMAND_SUFFIX

 [OM1|D|-1.57079649|53|0]