Пример #1
0
        private bool DetectBaudRate()
        {
            //Try with 9600 default value
            _port.Open();
            if (TrySendReceive())
            {
                return(true);
            }
            _port.ClearReceiveBuffer();
            _port.Close();

            //Try all known baud rates in descending order
            foreach (int key in BaudLookup.Keys.Reverse())
            {
                _port.BaudRate = key;
                _port.Open();
                if (TrySendReceive())
                {
                    return(true);
                }
                _port.ClearReceiveBuffer();
                _port.Close();
            }
            return(false);
        }
Пример #2
0
        /// <summary>
        /// Connect to the Arduino serial port
        /// </summary>
        /// <param name="portName">e.g. Com1</param>
        public async Task ConnectAsync(string portName)
        {
            await Task.Delay(0); // avoid CS1998

            Logger?.LogTrace($@"Connect: {portName}");

            // Create a new SerialPort object with default settings.
            Aborted = false;

            SetupCom(portName);

            _serialPortCancellationTokenSource = new CancellationTokenSource();

            _serialPort.Open();

            _readThread  = new Thread(Read);
            _writeThread = new Thread(Write);

            _readThread.Start();
            _writeThread.Start();

            // we need Dtr if not used as Reset
            // otherwise reset if dtr is set
            if (!DtrIsReset || ResetOnConnect)
            {
                _serialPort.DtrEnable = true;
            }
            else
            {
                _serialPort.DiscardOutBuffer();
                _serialPort.WriteLine("");
            }

            // _serialPort.DtrEnable = true;
            _serialPort.RtsEnable = true;

            bool wasEmpty;

            lock (_pendingCommands)
            {
                wasEmpty = _pendingCommands.Count == 0;
                _pendingCommands.Clear();
            }

            lock (_commands)
            {
                _commands.Clear();
            }

            if (!wasEmpty)
            {
                OnCommandQueueChanged(new SerialEventArgs(0, null));
            }

            OnCommandQueueEmpty(new SerialEventArgs(0, null));
        }
Пример #3
0
        public ISerialPort OpenPort(string portName, int baudRate,
                                    int dataBits, int readTimeout, int writeTimeout)
        {
            try
            {
                _serialPort.PortName      = portName;     //COM1
                _serialPort.BaudRate      = baudRate;     //9600
                _serialPort.DataBits      = dataBits;     //8
                _serialPort.Parity        = Parity.None;  //None
                _serialPort.StopBits      = StopBits.One; //1
                _serialPort.ReadTimeout   = readTimeout;  //300
                _serialPort.WriteTimeout  = writeTimeout; //300
                _serialPort.Encoding      = Encoding.GetEncoding("iso-8859-1");
                _serialPort.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
                _serialPort.Open();
                _serialPort.DtrEnable = true;
                _serialPort.RtsEnable = true;
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return(_serialPort); // Why???
        }
Пример #4
0
        public Vc0706(IIODevice device, SerialPortName portName, int baud)
        {
            serialPort = device.CreateSerialPort(portName, baud);

            /*serialPort = device.CreateSerialMessagePort(
             *          portName: portName,
             *          suffixDelimiter: Encoding.ASCII.GetBytes("\r\n"),
             *          baudRate: baud,
             *          preserveDelimiter: true,
             *          readBufferSize: 512);*/
            serialPort.Open();

            switch (baud)
            {
            case 9600:
            default:
                SetBaud9600();
                break;

            case 19200:
                SetBaud19200();
                break;

            case 38400:
                SetBaud38400();
                break;

            case 57600:
                SetBaud57600();
                break;
            }
        }
Пример #5
0
        public void ReadJson()
        {
            try
            {
                serialPort.Open();
                if (serial.GetPort().IsOpen)
                {
                    var result = json.ReadJson(serialPort);
                    Console.WriteLine(result.SensNr);
                    Console.WriteLine(result.InstNr);
                    Console.WriteLine(result.BRet);

                    /*for (int i = 0; i < json.Data.Count; i++)
                     * {
                     *  Console.WriteLine(result.Data[i]);
                     * }*/
                    Console.WriteLine(result.Data[0]);
                    Console.WriteLine(result.Data[1]);
                }
            }
            finally
            {
                serialPort.Close();
            }
        }
Пример #6
0
        private bool OpenSerialPort()
        {
            if (Output == "SerialPortMock")
            {
                m_serialport = MockSerialPort.Instance;
            }
            else
            {
                m_serialport = (ISerialPort) new CSerialPort();
            }

            bool opened = m_serialport.Open(Output, Rate);

            if (m_serialport.HasError())
            {
                Util.LogError($"{Name}: {m_serialport.GetError()}");
                if (opened)
                {
                    Util.Log($"{Name}: {Output} had a non fatal error, it might still work, continuing");
                }
            }

            m_serialport.PrintToStdOut(m_debug); //print serial data to stdout when debug mode is on

            return(opened);
        }
        /// <summary>
        /// Try to open the serial port.
        /// </summary>
        private async void TriggerOpenConnection(ISerialPort serialPort)
        {
            this.Log(LoggingMessageType.Info, "Serial Port communication started");

            var opened = false;
            var connectionErrorCount = 0;

            while ((!opened) && (_serialPort == serialPort))
            {
                try
                {
                    serialPort.Open();
                    opened = true;
                    connectionErrorCount     = 0;
                    _lastConnectTimestampUtc = DateTime.UtcNow;

                    this.Log(
                        LoggingMessageType.Info,
                        StringBuffer.Format("Successfully connected to port {0}", _portName));
                }
                catch (Exception ex)
                {
                    this.Log(
                        LoggingMessageType.Error,
                        StringBuffer.Format("Error while connecting to port {0}: {1}", _portName, ex.Message),
                        exception: ex);

                    connectionErrorCount++;
                    await Task.Delay(this.ReconnectWaitTimeGetter.GetWaitTime(connectionErrorCount));
                }
            }
        }
Пример #8
0
 private void OpenSerialPort(bool isUnitTest)
 {
     try
     {
         if (isUnitTest)
         {
             serialPort = new TestSerialPort();
         }
         else
         {
             serialPort = new SerialPortImpl();
         }
         serialPort.Open("COM" + Properties.Settings.Default.ComPort, 115200);
         AddInfo("Opened COM" + Properties.Settings.Default.ComPort);
         stopReading = false;
         if (!isUnitTest)
         {
             serialInputWorker         = new BackgroundWorker();
             serialInputWorker.DoWork += SerialInputWorker_DoWork;
             serialInputWorker.RunWorkerAsync();
             startToolStripMenuItem.Text = "Stop";
         }
     }
     catch (Exception ex)
     {
         AddInfo("Failed to open COM" + Properties.Settings.Default.ComPort + ": " + ex.Message);
     }
 }
Пример #9
0
        public void Open()
        {
            Port.Open();

            _portReadTask.Start();
            _processEventsTask.Start();
            _transmitTask.Start();
        }
Пример #10
0
        /// <summary>
        /// Open the hardware interface.
        /// </summary>
        public bool Open()
        {
            bool success = false;

            //
            try
            {
                //if (Environment.OSVersion.Platform.ToString().StartsWith("Win") == false)
                if (!System.IO.File.Exists(portName))
                {
                    logger.Error("port does not exist :" + portName);
                    return(success);
                }
                var controller = Platform.GetController();
                if (controller == null)
                {
                    logger.Error("controller not available");
                    return(success);
                }

                serialPort = controller.GetPort(portName);

                /*serialPort = new SerialPort();
                 * serialPort.PortName = portName;*/
                serialPort.SerialSettings.BaudRate_Int = 4800;
                serialPort.SerialSettings.Parity       = Parity.None;
                serialPort.SerialSettings.DataBits     = DataBits.D8;
                serialPort.SerialSettings.StopBits     = StopBits.One;
                serialPort.SerialSettings.Handshake    = Handshake.None;
                serialPort.BufferSettings.ReadTimeout  = 150;
                serialPort.BufferSettings.WriteTimeout = 150;
                serialPort.PinStates.Rts_Enable        = false;
                serialPort.PinStates.Dtr_Enable        = false;

                // DataReceived event won't work under Linux / Mono
                //serialPort.DataReceived += HandleDataReceived;
                //serialPort.ErrorReceived += HanldeErrorReceived;

                if (serialPort.IsOpen == false)
                {
                    serialPort.Open();
                }
                // Send status request on connection
                //this.WriteData(new byte[] { (byte)X10CommandType.PLC_StatusRequest });
                serialPort.Uart.DiscardInBuffer();
                serialPort.Uart.DiscardOutBuffer();

                success = true;
            }
            catch (Exception e)
            {
                logger.Error(e);
            }

            return(success);
        }
Пример #11
0
        /// <summary>
        ///     Open the serial port and start processing the data from the serial port.
        /// </summary>
        public void Open()
        {
            //Console.WriteLine("SerialTextFile: Open");

            if (!serialPort.IsOpen)
            {
                //Console.WriteLine("SerialTextFile: _serialPort.Open");
                serialPort.Open();
            }
        }
Пример #12
0
        protected void OpenComPort(string port = "COM1", int baudRate = 38400)
        {
            CloseComPort();

            //ToDo  serialPort = new SerialPort(port, baudRate, Parity.None, 8, StopBits.One);

            serialPort.ReadTimeout = 10 * 2;
            // serialPort.WriteTimeout = 10 * 2;

            serialPort.Open();
        }
Пример #13
0
        public async Task Open(bool softReset)
        {
            await Port.Open();

            if (softReset)
            {
                await SoftReset();
            }

            _broker.Run(_cancellationSource.Token);
        }
Пример #14
0
        /// <summary>
        /// Connect to the Arduino serial port
        /// </summary>
        /// <param name="portname">e.g. Com1</param>
        public async Task ConnectAsync(string portname)
        {
            // Create a new SerialPort object with default settings.
            Aborted = false;

            SetupCom(portname);

            _serialPortCancellationTokenSource = new CancellationTokenSource();
            _serialPort.Open();

            _readThread  = new Thread(Read);
            _writeThread = new Thread(Write);

            _readThread.Start();
            _writeThread.Start();

            if (!ResetOnConnect)
            {
                _serialPort.DiscardOutBuffer();
                _serialPort.WriteLine("");
            }

            bool wasempty;

            lock (_pendingCommands)
            {
                wasempty = _pendingCommands.Count == 0;
                _pendingCommands.Clear();
            }
            lock (_commands)
            {
                _commands.Clear();
            }

            if (!wasempty)
            {
                OnComandQueueChanged(new SerialEventArgs(0, null));
            }

            OnComandQueueEmpty(new SerialEventArgs(0, null));
        }
Пример #15
0
        public SerialDevice(string COM_Port)
        {
            sp.PortName = COM_Port;
            sp.BaudRate = BAUDRATE;
            sp.DtrEnable = true;
            sp.Open();

            var r = RunCommand(SysExMsg.MSG_GET_HANDSHAKE, CommandType.Get);
            if (r.Values.Length != 2) throw new Exception($"Not a valid aDrum response in {COM_Port}");
            aDrumVersion = new Version(r.Values[0], r.Values[1]);

        }
Пример #16
0
        public SerialDevice(ISerialPort serialPort)
        {
            _sp = serialPort;
            _sp.BaudRate = BAUDRATE;
            _sp.DtrEnable = true;
            _sp.Open();

            var r = RunCommand(SysExMsg.Handshake, CommandType.Get);
            if (r.Values.Length != 2) throw new Exception($"Not a valid aDrum response in {serialPort.PortName}");
            aDrumVersion = new Version(r.Values[0], r.Values[1]);

        }
Пример #17
0
        /// <summary>
        ///     Create a new SerialLcd object.
        /// </summary>
        /// <param name="config">TextDisplayConfig object defining the Lcd dimension (null will default to 16x2).</param>
        /// <param name="baudRate">Baud rate to use (default = 9600).</param>
        /// <param name="parity">Parity to use (default is None).</param>
        /// <param name="dataBits">Number of data bits (default is 8 data bits).</param>
        /// <param name="stopBits">Number of stop bits (default is one stop bit).</param>
        public SerialLcd(IIODevice device, SerialPortName port, TextDisplayConfig config = null, int baudRate = 9600,
                         Parity parity = Parity.None, int dataBits = 8, StopBits stopBits = StopBits.One)
        {
            if (config == null)
            {
                // assume a 16x2 Lcd.
                DisplayConfig = new TextDisplayConfig()
                {
                    Height = 2, Width = 16
                };
            }
            else
            {
                DisplayConfig = config;
            }

            comPort = device.CreateSerialPort(port, baudRate, dataBits, parity, stopBits);

            comPort.Open();

            // configure the Lcd controller for the appropriate screen size
            byte lines      = 0;
            byte characters = 0;

            switch (DisplayConfig.Width)
            {
            case 16:
                characters = (byte)LcdDimensions.Characters16Wide;
                break;

            case 20:
                characters = (byte)LcdDimensions.Characters20Wide;
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(config.Width), "Display width should be 16 or 20.");
            }
            switch (DisplayConfig.Height)
            {
            case 2:
                lines = (byte)LcdDimensions.Lines2;
                break;

            case 4:
                lines = (byte)LcdDimensions.Lines4;
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(config.Height), "Display height should be 2 or 4 lines.");
            }
            Send(new[] { ConfigurationCommandCharacter, characters, ConfigurationCommandCharacter, lines });
            Thread.Sleep(10);
        }
Пример #18
0
        protected Yx5300(ISerialPort serialPort)
        {
            this.serialPort = serialPort;

            serialPort.Open();

            SendCommand(Commands.Reset);

            Thread.Sleep(100);

            SendCommand(Commands.SelectDevice, 0, 2);

            Thread.Sleep(500);
        }
Пример #19
0
        public override async Task <bool> Enable()
        {
            if (!await port.Open(115200))
            {
                return(false);
            }
            await Task.Delay(3000);

            port.Flush();
            isEnabled = true;

            Console.WriteLine($"{id} Enabled");
            return(true);
        }
Пример #20
0
        private void WriteSerialData(string msg)
        {
            switch (CurrentTransmissionType)
            {
            case TransmissionType.Text:
                //first make sure the port is open
                //if its not open then open it
                if (!(comSerialPort.IsOpen == true))
                {
                    comSerialPort.Open(_serialPortConnectInformation);
                }
                //send the message to the port
                comSerialPort.Write(msg + "\r");      // Add 0x0D at the end, to match Nuvo Essentia needs
                //display the message
                DisplayData(MessageType.Outgoing, msg + "\n");
                break;

            case TransmissionType.Hex:
                //display error message
                DisplayData(MessageType.Error, "Transmission type 'Hex' is not supported for this serial port");
                break;

            default:
                //first make sure the port is open
                //if its not open then open it
                if (!(comSerialPort.IsOpen == true))
                {
                    comSerialPort.Open(_serialPortConnectInformation);
                }
                //send the message to the port
                comSerialPort.Write(msg);
                //display the message
                DisplayData(MessageType.Outgoing, msg + "\n");
                break;
            }
        }
Пример #21
0
        private void ConfigurePort(ISerialPort serialPort)
        {
            serialPort.BaudRate = BAUD_RATE;
            serialPort.NewLine  = NEWLINE;
            serialPort.StopBits = STOP_BITS;
            serialPort.DataBits = DATA_BITS;
            serialPort.Parity   = PARITY;

            serialPort.Handshake    = HAND_SHAKE;
            serialPort.ReadTimeout  = READ_TIMEOUT;
            serialPort.WriteTimeout = WRITE_TIMEOUT;

            serialPort.Open();
            serialPort.DiscardInBuffer();
            serialPort.DiscardOutBuffer();
        }
 private bool EnsureSerialPortConnected()
 {
     lock (_serialPortLock)
     {
         if (_serialPort == null)
         {
             try
             {
                 _serialPort = new SerialPort(_config.COMPort, BAUD_RATE, PARITY, DATA_BITS, STOP_BITS);
             }
             catch (Exception e)
             {
                 _log.Error(e.Message, e);
                 return(false);
             }
         }
         if (_serialPort != null && !_serialPort.IsOpen &&
             _unsuccessfulConnectionAttempts < MAX_UNSUCCESSFUL_PORT_OPEN_ATTEMPTS)
         {
             try
             {
                 _serialPort.Handshake       = HANDSHAKE;
                 _serialPort.WriteTimeout    = SERIAL_WRITE_TIMEOUT;
                 _serialPort.ErrorReceived  += _serialPort_ErrorReceived;
                 _serialPort.WriteBufferSize = WRITE_BUFFER_SIZE;
                 _log.DebugFormat(
                     $"Opening serial port {_config.COMPort}: Handshake:{HANDSHAKE}, WriteTimeout:{SERIAL_WRITE_TIMEOUT}, WriteBufferSize:{WRITE_BUFFER_SIZE}");
                 _serialPort.Open();
                 GC.SuppressFinalize(_serialPort.BaseStream);
                 _serialPort.DiscardOutBuffer();
                 _unsuccessfulConnectionAttempts = 0;
                 return(true);
             }
             catch (Exception e)
             {
                 _unsuccessfulConnectionAttempts++;
                 _log.Error(e.Message, e);
             }
         }
         else if (_serialPort != null && _serialPort.IsOpen)
         {
             return(true);
         }
         return(false);
     }
 }
Пример #23
0
        public void Open()
        {
            Port.Open();

            // create tasks, on open or re-open
            _eventQueue    = new BlockingCollection <Message>();
            _transmitQueue = new BlockingCollection <Message>();
            _responseQueue = new BlockingCollection <Message>();

            _processEventsTask = new Task(() => ProcessQueue(_eventQueue, OnNodeMessageReceived));
            _transmitTask      = new Task(() => ProcessQueue(_transmitQueue, OnTransmit));
            _portReadTask      = new Task(() => ReadPort(Port));

            // start tasks
            _portReadTask.Start();
            _processEventsTask.Start();
            _transmitTask.Start();
        }
Пример #24
0
        public TiDongle(ISerialPort Port, IGUI Gui)
        {
            _receiveParserThread = new Thread(ParseReceive);
            _receiveParserThread.IsBackground = true;
            _port = Port;
            if (_port != null)
            {
                _port.Open();
                FixComunicationProblem();
            }

            _gui                = Gui;
            init_success        = false;
            device_connected    = false;
            device_disconnected = false;

            _receiveParserThread.Start();
        }
Пример #25
0
 /// <summary>
 /// Open Arduino Com Port
 /// </summary>
 /// <exception cref="InvalidOperationException">Thrown in case of error while opening port</exception>
 public void OpenArduinoComPort()
 {
     if (_comPort == null)
     {
         _comPort = new SerialPortWrapper(_comPortName, Communication.BAUDRATE);
     }
     try
     {
         Log.Print(String.Format("Opening Arduino port {0}...", _comPortName), eCategory.Info, LogTag.COMMUNICATION);
         _comPort.Open();
     }
     catch (Exception ex)
     {
         throw new InvalidOperationException(String.Format("[{0}] Error opening Arduino port {1}. Reason: {2}",
                                                           MethodBase.GetCurrentMethod().Name, _comPortName, ex.Message), ex);
     }
     Log.Print(String.Format("Arduino port {0} is open!", _comPortName), eCategory.Info, LogTag.COMMUNICATION);
 }
Пример #26
0
        private void ConfigurePortForDiscovery(ISerialPort serialPort)
        {
            serialPort.ReadBufferSize  = READ_BUFFER_SIZE;
            serialPort.WriteBufferSize = WRITE_BUFFER_SIZE;

            serialPort.BaudRate = BAUD_RATE;
            serialPort.NewLine  = NEWLINE;
            serialPort.StopBits = STOP_BITS;
            serialPort.DataBits = DATA_BITS;
            serialPort.Parity   = PARITY;

            //Not sure why the following three are differnet during discovery.
            serialPort.Handshake    = Handshake.RequestToSendXOnXOff; //Because it works for either K24 or WK43
            serialPort.ReadTimeout  = 1000;
            serialPort.WriteTimeout = 1000;

            serialPort.Open();
            serialPort.DiscardInBuffer();
            serialPort.DiscardOutBuffer();
        }
        public MainPage()
        {
            InitializeComponent();
            serialPort           = DependencyService.Get <ISerialPort>();
            serialPort.Received += (s, data) =>
            {
                recvCount += data.Length;
            };
            serialPort.Open("/dev/ttyS3", 115200);

            Task.Run(() =>
            {
                var sendBuffer = new byte[234];
                for (byte i = 0; i < sendBuffer.Length; i++)
                {
                    sendBuffer[i] = i;
                }

                while (true)
                {
                    //System.Diagnostics.Debug.WriteLine($"Count:{sendCount} {recvCount}");
                    //Device.BeginInvokeOnMainThread(() =>
                    //{
                    //    labSend.Text = $"Send:{sendCount}";
                    //    labRecv.Text = $"Recv:{recvCount}";
                    //});

                    serialPort.Send(sendBuffer);
                    sendCount += sendBuffer.Length;
                    Thread.Sleep(200);
                }
            });

            Device.StartTimer(TimeSpan.FromMilliseconds(500), () =>
            {
                labSend.Text = $"Send:{sendCount}";
                labRecv.Text = $"Recv:{recvCount}";
                // do something every 60 seconds
                return(true); // runs again, or false to stop
            });
        }
Пример #28
0
        public void connect(ISerialPort sp)
        {
            if (connectionState == ConnectionState.Connected)
            {
                throw new InvalidOperationException();
            }

            if (sp == null)
            {
                throw new ArgumentNullException("sp");
            }

            if (!sp.IsOpen)
            {
                sp.Open();
            }

            _sp = sp;

            connectionState = ConnectionState.Connected;
        }
Пример #29
0
        public bool Connect()
        {
            bool rt = false;

            try
            {
                if (ISerialPort != null)
                {
                    if (ISerialPort.IsOpen)
                    {
                        ISerialPort.DataReceived -= SerialPort_DataReceived;
                        ISerialPort.Close();
                        System.Threading.Thread.Sleep(100);
                        ISerialPort.Dispose();
                    }

                    ISerialPort.BaudRate = Property.BaudRate;
                    ISerialPort.Parity   = Property.Parity;
                    ISerialPort.DataBits = Property.DataBits;
                    ISerialPort.StopBits = Property.StopBits;
                    //ISerialPort.ReceivedBytesThreshold = ComSerialPort.ReceivedBytesThreshold;
                    ISerialPort.NewLine       = Property.NewLine;
                    ISerialPort.ReadTimeout   = Property.ReceiveTimeOut;
                    ISerialPort.DtrEnable     = Property.DtrEnable;
                    ISerialPort.RtsEnable     = Property.RtsEnable;
                    ISerialPort.DataReceived += SerialPort_DataReceived;
                    System.AsyncCallback OnConnected = new System.AsyncCallback(ConnectedCallBack);

                    //当完成连接后回调:OnConnected委托
                    ISerialPort.Open();
                    OnConnected(null);
                    rt = true;
                }
            }
            catch (Exception ex) { }
            finally { }
            return(rt);
        }
Пример #30
0
 private void Open()
 {
     //_session.IsTryingConnect = true;
     try
     {
         _port.Open();
         _port.DiscardInBuffer();
         _session.Connected = true;
         return;
     }
     catch (IOException e)
     {
         Console.WriteLine("Serial IO error in opening: {0}", e.Message);
         _session.Connected = false;
         StopConnection();
         return;
     }
     catch (InvalidOperationException e)
     {
         Console.WriteLine("Serial invalid operation error: {0}", e.Message);
     }
     StopConnection();
     _session.Connected = false;
 }
Пример #31
0
        private void CreateSerialPort()
        {
            if (_serialPort != null)
            {
                // Close already open port
                Close();
            }

            if (_serialPortPassedByCaller != null)
            {
                _log.Debug(m => m("Start of NuvoTelegram .... use passed-in serial port object!"));
                _serialPort = _serialPortPassedByCaller;
            }
            else
            {
                _log.Debug(m => m("Start of NuvoTelegram .... create own serial port object!"));
                if (_serialPortConnectInformation.PortName.Equals(defaultPortSim))
                {
                    // Create serial port simulator
                    _serialPort = new ProtocolDriverSimulator();
                }
                else if (_serialPortConnectInformation.PortName.Equals(defaultPortQueue))
                {
                    // Create serial port queue
                    _serialPort = new SerialPortQueue();
                }
                else
                {
                    _serialPort = new SerialPort();
                }
            }

            // Register for events and open serial port
            _serialPort.onDataReceived += new SerialPortEventHandler(serialPort_DataReceived);
            _serialPort.Open(_serialPortConnectInformation);
        }
        public Dictionary<PropertyKey, int> Connect(InsteonConnection connection)
        {
            port?.Close();

            port = SerialPortCreator.Create(connection);
            port.Open();

            byte[] input = { Constants.MessageStartByte, (byte)InsteonModemSerialCommand.GetImInfo };
            var properties = new Dictionary<PropertyKey, int>();
            var response = new List<byte>();

            try
            {
                for (int i = 1; i <= Constants.negotiateRetries; ++i)
                {
                    logger.DebugFormat("TX: {0}", Utilities.ByteArrayToString(input));
                    port.Write(input);

                    port.Wait(Constants.openTimeout);
                    var output = port.ReadAll();
                    if (output.Length <= 0)
                    {
                        Thread.Sleep(100);
                        continue; // try again
                    }

                    response.Clear();
                    response.AddRange(output);

                    while (output.Length > 0 && response.Count < 9)
                    {
                        port.Wait(Constants.openTimeout);
                        output = port.ReadAll();
                        response.AddRange(output);
                    }

                    logger.DebugFormat("RX: {0}", Utilities.ByteArrayToString(response.ToArray()));

                    int offset = 0;

                    // determins the start location of the actual message returned
                    for (int j = 0; j < response.Count; ++j)
                    {
                        if (response[j] == Constants.MessageStartByte)
                        {
                            offset = j;
                        }
                    }

                    if (response.Count >= offset + 9 &&
                        response[offset] == Constants.MessageStartByte &&
                        response[offset + 1] == (byte)InsteonModemSerialCommand.GetImInfo &&
                        response[offset + 8] == Constants.MessageEndByte)
                    {
                        properties[PropertyKey.Address] = response[offset + 2] << 16 | response[offset + 3] << 8 | response[offset + 4];
                        properties[PropertyKey.DevCat] = response[offset + 5];
                        properties[PropertyKey.SubCat] = response[offset + 6];
                        properties[PropertyKey.FirmwareVersion] = response[offset + 7];
                        break; // found
                    }
                }
            }
            finally
            {
                if (response.Count == 0)
                {
                    throw new IOException("Failed to open port, timeout waiting for response from port.");
                }

                if (properties.Keys.Count == 0)
                {
                    port.Close();
                    port = null;
                    throw new IOException("Failed to open port, unable to negotiate with INSTEON controller.");
                }
            }

            logger.DebugFormat("Successfully negotiated with INSTEON controller on connection '{0}'...", connection);
            port.SetNotify(DataAvailable);
            return properties;
        }