/// <summary>
        /// Creates an instance of the ELM327 driver.
        /// </summary>
        /// <param name="serialPortName">The name of the serial port the ELM is connected to
        /// ("COM1", "COM2", etc.).</param>
        /// <param name="protocolType">The desired OBD protocol to use.  Using
        /// <see cref="Elm327.Core.ElmDriver.ElmObdProtocolType.Automatic"/> is usually a good idea.</param>
        /// <param name="measuringUnit">The desired unit type for reporting readings.</param>
        public ElmDriver(
            string serialPortName,
            ElmObdProtocolType protocolType,
            ElmMeasuringUnitType measuringUnit)
        {
            this.MeasuringUnitType = measuringUnit;
            this.ElmVersionID      = string.Empty;
            this.ObdMode01         = new ObdGenericMode01(this);
            this.ObdMode09         = new ObdGenericMode09(this);
            this.protocolType      = protocolType;
            this.receiveBuffer     = new byte[ElmDriver.RECEIVE_BUFFER_SIZE];

            this.serialPort = new SerialPort(
                serialPortName,
                ElmDriver.BAUD_RATE,
                Parity.None,
                8,
                StopBits.One);

            this.serialPort.ErrorReceived += new SerialErrorReceivedEventHandler(ElmDriver.uart_ErrorReceived);
        }
        /// <summary>
        /// Attempts to open a connection to the ELM chip.
        /// </summary>
        /// <returns>A value indicating the result of the connection attempt.</returns>
        public ElmConnectionResultType Connect()
        {
            // Try to force the connection closed if it is open and the caller wants to
            // reinitialize

            lock (this.serialPort)
            {
                if (this.serialPort.IsOpen)
                {
                    // TODO: This is untested

                    try
                    {
                        this.serialPort.Close();
                    }
                    catch (Exception ex)
                    {
                        Util.Log(ex);
                    }
                }
            }

            // Try to open the COM port

            lock (this.serialPort)
            {
                try
                {
                    this.serialPort.Open();
                    this.serialPort.Flush();
                    this.serialPort.DiscardInBuffer();
                    this.serialPort.DiscardOutBuffer();
                }
                catch (Exception ex)
                {
                    Util.Log(ex);
                    return(ElmConnectionResultType.NoConnectionToElm);
                }
            }

            // Perform a reset on the ELM.  If we get a null back from this call,
            // it means we're unable to see it (probably a wiring issue).

            if (this.SendAndReceiveMessage("ATZ") == null)
            {
                return(ElmConnectionResultType.NoConnectionToElm);
            }

            // Turn line feeds and echo off, turn on space printing (as our code currently
            // expects it) and retrieve the ELM's version information
            // TODO: ELM responses will be faster if we turn off space printing, but leaving
            // as-is for now to enable easy message parsing

            this.SendAndReceiveMessage("ATL0");
            this.SendAndReceiveMessage("ATE0");
            this.SendAndReceiveMessage("ATS1");
            this.ElmVersionID = this.SendAndReceiveMessage("ATI");

            // Set the caller's desired protocol, then make a simple "0100" call to
            // make sure the ECU responds.  If we get anything back other than something
            // that starts with "41 00", it means the ELM can't talk to the OBD
            // system.

            this.ProtocolType = this.protocolType;

            string response = this.SendAndReceiveMessage("0100");

            if (response == null || response.IndexOf("41 00") != 0)
            {
                return(ElmConnectionResultType.NoConnectionToObd);
            }

            // Ask the ELM to give us the protocol it's using.  We need to ask for
            // this value in case the user chose the "Automatic" setting for protocol
            // type, so we'll know which protocol was actually selected by the ELM.

            response = this.SendAndReceiveMessage("ATDPN");

            if (response != null && response.Length > 0)
            {
                try
                {
                    // 'A' will be the first character returned if the user chose
                    // automatic search mode

                    if (response[0] == 'A' && response.Length > 1)
                    {
                        this.protocolType = (ElmObdProtocolType)response[1];
                    }
                    else
                    {
                        this.protocolType = (ElmObdProtocolType)response[0];
                    }
                }
                catch (Exception ex)
                {
                    Util.Log(ex);
                }
            }

            return(ElmConnectionResultType.Connected);
        }