public object Execute(ArduinoFunction function)
        {
            var result = port.Send(function);

            object netObject = null;

            switch (function.ReturnType)
            {
            case SupportedType.BOOLEANT:
                netObject = result[0] == 0 ? false : true;
                break;

            case SupportedType.CHART:
                netObject = (sbyte)result[0];
                break;

            case SupportedType.UCHART:
                netObject = result[0];
                break;

            case SupportedType.BYTET:
                netObject = result[0];
                break;

            case SupportedType.INTT:
                netObject = BitConverter.ToInt16(result, 0);
                break;

            case SupportedType.UINTT:
                netObject = BitConverter.ToUInt16(result, 0);
                break;

            case SupportedType.LONG:
                netObject = BitConverter.ToInt32(result, 0);
                break;

            case SupportedType.ULONG:
                netObject = BitConverter.ToUInt32(result, 0);
                break;

            case SupportedType.SHORT:
                netObject = BitConverter.ToInt16(result, 0);
                break;
            }

            return(netObject);
        }
        internal byte[] Send(ArduinoFunction request, int maxSendRetries = MaxSendRetries)
        {
            var sendRetries = 0;

            while (sendRetries++ < maxSendRetries)
            {
                try
                {
                    // First try to get sync (send FF FE FD FC and require FC FD FE FF as a response).
                    bool hasSync;
                    var  syncRetries = 0;
                    while (!(hasSync = GetSync()) && syncRetries++ < MaxSyncRetries)
                    {
                    }
                    if (!hasSync)
                    {
                        var errorMessage = string.Format("Unable to get sync after {0} tries!", MaxSyncRetries);
                        throw new IOException(errorMessage);
                    }

                    // Now send the command handshake (send FB as start of message marker + the command byte + length byte).
                    // Expect the inverse (length byte followed by command byte followed by FB) as a command ACK.
                    var requestBytes       = request.GetDataBytes().ToArray();
                    var requestBytesLength = requestBytes.Length;

                    if (!ExecuteCommandHandShake(request.FunctionId, (byte)requestBytesLength))
                    {
                        var errorMessage = string.Format("Unable to configure command handshake for command {0}.", request);
                        //logger.Warn(errorMessage);
                        throw new IOException(errorMessage);
                    }

                    // Write out all packet bytes, followed by a Fletcher 16 checksum!
                    // Packet bytes consist of:
                    // 1. Command byte repeated
                    // 2. Request length repeated
                    // 3. The actual request bytes
                    // 4. Two fletcher-16 checksum bytes calculated over (1 + 2 + 3)
                    var packetBytes = new byte[requestBytesLength + 4];
                    packetBytes[0] = request.FunctionId;
                    packetBytes[1] = (byte)requestBytesLength;
                    Buffer.BlockCopy(requestBytes, 0, packetBytes, 2, requestBytesLength);
                    var fletcher16CheckSum = CalculateFletcher16Checksum(packetBytes, requestBytesLength + 2);
                    var f0 = (byte)(fletcher16CheckSum & 0xff);
                    var f1 = (byte)((fletcher16CheckSum >> 8) & 0xff);
                    var c0 = (byte)(0xff - (f0 + f1) % 0xff);
                    var c1 = (byte)(0xff - (f0 + c0) % 0xff);
                    packetBytes[requestBytesLength + 2] = c0;
                    packetBytes[requestBytesLength + 3] = c1;

                    serialStream.Write(packetBytes, 0, requestBytesLength + 4);

                    // Write out all bytes written marker (FA)
                    serialStream.Write(new[] { CommandConstants.AllBytesWritten }, 0, 1);

                    // Expect response message to drop to be received in the following form:
                    // F9 (start of response marker) followed by response length
                    var responseBytes         = ReadCurrentReceiveBuffer(2);
                    var startOfResponseMarker = responseBytes[0];
                    var responseLength        = responseBytes[1];
                    if (startOfResponseMarker != CommandConstants.StartOfResponseMarker)
                    {
                        var errorMessage = string.Format("Did not receive start of response marker but {0}!", startOfResponseMarker);
                        throw new IOException(errorMessage);
                    }

                    // Read x responsebytes
                    if (responseLength == 0xfc)
                    {
                        return(null);
                    }

                    responseBytes = ReadCurrentReceiveBuffer(responseLength);
                    return(responseBytes);
                }
                catch (TimeoutException ex)
                {
                    // logger.Debug(ex, "TimeoutException in Send occurred, retrying ({0}/{1})!", sendRetries, MaxSendRetries);
                }
                catch (Exception ex)
                {
                    // logger.Debug("Exception: '{0}'", ex.Message);
                }
            }
            return(null);
        }