Alexander Benjamin
Alexander Benjamin

Reputation: 83

Reconnecting to COM after lost connection

I cannot reconnect to COM port after device on the other end abruptly drops connection. I can connect again only if I close and re-open the application.

Here is my connection function:

public bool connectTurboPump()
    {
        try
        {
            if (TPumpSerialPort != null && TPumpSerialPort.IsOpen == true)
                return true;

            DataRow dr = tblTPump.Rows[0];

            Types.Connection TPumpConnection = new Types.Connection();
            TPumpConnection.PORT = dr["port"].ToString();
            TPumpConnection.BAUD_RATE = Convert.ToInt32(dr["baud"]);
            TPumpConnection.PARITY = (Parity)Enum.Parse(typeof(Parity), dr["parity"].ToString(), true);
            TPumpConnection.DATA_BITS = Convert.ToInt32(dr["dataBits"]);
            TPumpConnection.STOP_BITS = (StopBits)Enum.Parse(typeof(StopBits), dr["stopBits"].ToString(), true);
            TPumpConnection.HANDSHAKE = (Handshake)Enum.Parse(typeof(Handshake), dr["handshake"].ToString(), true);

            TPumpSerialPort = new SerialPort(TPumpConnection.PORT, TPumpConnection.BAUD_RATE, TPumpConnection.PARITY, TPumpConnection.DATA_BITS, TPumpConnection.STOP_BITS);
            TPumpSerialPort.Handshake = TPumpConnection.HANDSHAKE;
            TPumpSerialPort.Open();
            TPumpSerialPort.NewLine = "\r";
            TPumpSerialPort.ReadTimeout = 10000;
            TPumpSerialPort.WriteTimeout = 10000;

            if (TPumpSerialPort.IsOpen != true)
                return false;

            return true;
        }
        catch { return false; }
    }

And here is my re-connection function:

public bool reconnectTurboPump(int attempts = 3)
    {
        try
        {
            if (TPumpSerialPort != null && TPumpSerialPort.IsOpen == true)
            {
                TPumpSerialPort.Close();
                TPumpSerialPort.Dispose();
            }

            int i = 1;
            while (true)
            {
                Log(string.Format("Reconnecting Turbo Pump attempt {0}", i));

                if (connectTurboPump())
                    break;

                if (i == attempts)
                    return false;

                i++;
            }

            return true;
        }
        catch (Exception ex)
        {
            Log(string.Format("Could not reconnect to Turbo Pump: {0}", ex.Message));
            return false;
        }
    }

Would really appreciate if someone could help.

Thank you.

Upvotes: 1

Views: 6476

Answers (2)

Hans Passant
Hans Passant

Reputation: 941267

This doesn't make much sense if this is a true serial port connection. There is no "connected" state, serial ports are very simple devices that have no underlying protocol that establishes a connection.

If this is actually a USB device that emulates a serial port then you'll indeed have this kind of problem. The driver that emulates the serial port invariably gets very sulky when you unplug the USB connector while the port is in use. There actually is a connection protocol for USB devices, the negotiation is done by the driver. They most typically make the port just disappear, this tends to give user code a heart-attack from which it can't recover. Behavior is very unpredictable and varies from one driver to another. There is no cure for this, glue the connector to the port and never assume that unplugging it will solve any problems in your code, even though that's the only thing you can do with USB.

Upvotes: 2

Alexander Benjamin
Alexander Benjamin

Reputation: 83

Following Thomas' advice I've changed reconnection script to the following. Now in testing.

 public bool reconnectTurboPump(int attempts = 3)
    {
        try
        {
            //if (TPumpSerialPort != null && TPumpSerialPort.IsOpen == true)
            if (TPumpSerialPort != null)
            {
                TPumpSerialPort.Close();
                TPumpSerialPort.Dispose();
            }

            int i = 1;
            while (true)
            {
                Log(string.Format("Reconnecting Turbo Pump attempt {0}", i));

                Thread.Sleep(2000);

                if (connectTurboPump())
                    break;

                if (i == attempts)
                    return false;

                i++;
            }

            return true;
        }
        catch (Exception ex)
        {
            Log(string.Format("Could not reconnect to Turbo Pump: {0}", ex.Message));
            return false;
        }
    }

Upvotes: 0

Related Questions