// ------------------------------------------------------------------------
 /// <summary>Disconnect from bus controller.</summary>
 public void Disconnect()
 {
     if (MBmaster != null)
     {
         MBmaster.Dispose();
         MBmaster = null;
         BCinfo   = null;
     }
     else
     {
         return;
     }
     _connected = false;
     RefreshTimer.Change(0, 0);
     ReconnectTimer = new Timer(new TimerCallback(ReconnectTimer_Elapsed), this, 10000, 10000);
 }
        // ------------------------------------------------------------------------
        /// <summary>Connect to bus controller.</summary>
        /// <param name="ip">IP adress or host name of the X20BC0087 controller.
        /// See FAQ section for more information how to determinate the host name.</param>
        /// <param name="port">Port number of X20BC0087 controller. Usually port 502 is used.</param>
        public void Connect(string ip, ushort port)
        {
            byte[] result = { };

            while (ReconnectTimer != null)
            {
                Thread.Sleep(100);
            }

            try
            {
                MBmaster = new Master(ip, port, false);
                MBmaster.OnResponseData += new ModbusTCP.Master.ResponseData(MBmaster_OnResponseData);
                MBmaster.OnException    += new ModbusTCP.Master.ExceptionData(MBmaster_OnException);
                _connected = true;

                // Disable boundary check
                MBmaster.WriteSingleRegister(MasterBR.ID_boundary, 0, 0x1182, BitConverter.GetBytes((short)IPAddress.HostToNetworkOrder((short)0xC0)), ref result);
                // Retry when bus coupler is still booting up retry after 10s
                if (result == null)
                {
                    Thread.Sleep(10000);
                    MBmaster.WriteSingleRegister(MasterBR.ID_boundary, 0, 0x1182, BitConverter.GetBytes((short)IPAddress.HostToNetworkOrder((short)0xC0)), ref result);
                    if (result == null)
                    {
                        _connected = false;
                        if (MBmaster != null)
                        {
                            MBmaster.Dispose();
                            MBmaster = null;
                            BCinfo   = null;
                        }
                        throw new System.Net.Sockets.SocketException();
                    }
                }

                // Read module info, disable boundary check
                BCinfo = new MasterBR_BCinfo(this);
                MasterMDinfo();

                dig_in_length  = Convert.ToUInt16(BCinfo.process_digital_inp_cnt * 8);
                dig_in_buffer  = new bool[dig_in_length];
                dig_out_length = Convert.ToUInt16(BCinfo.process_digital_out_cnt * 8);
                dig_out_buffer = new bool[dig_out_length];
                ana_in_length  = Convert.ToUInt16(BCinfo.process_analog_inp_cnt);
                ana_in_buffer  = new int[ana_in_length];
                ana_out_length = Convert.ToUInt16(BCinfo.process_analog_out_cnt * 8);
                ana_out_buffer = new int[ana_out_length];
            }
            catch (Exception error)
            {
                _connected = false;
                if (MBmaster != null)
                {
                    MBmaster.Dispose();
                    MBmaster = null;
                    BCinfo   = null;
                }
                throw (error);
            }
        }