1

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.

Roman R.
  • 68,205
  • 6
  • 94
  • 158
  • 1
    Please take a look at this link: http://stackoverflow.com/questions/4369679/com-port-is-denied. I think you'll find several applicable suggestions. – paulsm4 Aug 09 '12 at 19:59
  • What happens if you change `if (TPumpSerialPort != null && TPumpSerialPort.IsOpen == true)` to just `if (TPumpSerialPort != null)`? – Monroe Thomas Aug 09 '12 at 20:06
  • After evaluating 10+ serial port solutions, I only found one that worked. You can see my answer here for details: http://stackoverflow.com/a/8003897/362536 I don't know if that problem applies to you, but if it does, I recommend checking out CommStudio. – Brad Aug 09 '12 at 20:07
  • Brad, I could not install CommStudio on Windows 7 64-it – Alexander Benjamin Aug 10 '12 at 08:07

2 Answers2

2

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.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • +1 That sounds right to me to. I think @paulm4 link in the comments sounds like a way to tickle the USB driver. http://stackoverflow.com/questions/4369679/com-port-is-denied – kenny Aug 10 '12 at 12:53
  • In my case this is direct RS232 connection without any adapters. – Alexander Benjamin Aug 11 '12 at 20:04
  • Then my first paragraph applies. Never call SerialPort.Open immediately after Close. It doesn't work, a worker thread needs to shut down and that takes an unpredictable amount of time. And there's no point. I can't otherwise see what connectTurboPump() might do. – Hans Passant Aug 11 '12 at 20:12
0

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;
        }
    }