I am prototyping a sort of Arduino-based docking station for a tablet, using the USB port as connector. This means I need to support to ability to plug/unplug the USB connector while the application on the tablet is running.
The tablet runs a c# application (.net 4.5 on Win7 64 bit) in which I am connecting to the Arduino Uno. When the application is launched I loop all available COM ports using:
var ports = SerialPort.GetPortNames(); // -> [COM3,COM4,COM8]
foreach (var port in ports)
{
var serial = new SerialPort(portname, baudRate);
//attempt handshake and connect to right port
}
This work fine, but if I unplug and replug the USB cable and reattempt to reconnect to the Arduino (while the application is still running), the Arduino port (COM8) is no longer listed in:
SerialPort.GetPortNames(); // -> [COM3,COM4] and no COM8
Even restarting the application (with the Arduino replugged) will result in only [COM3,COM4] being listed.
The only way to get it back to work is to unplug and replug the Arduino while the application is not running.
What confuses me is the fact that when I plug in the Arduino Uno after starting the application, the SerialClass does recognize the newly added port and allows me to connect.
The problem only occurs when I unplug and replug the device when the application is running. It seems that despite the ability to reset the COM port (in code or manually in device manager), the SerialClass (and native Win32_SerialPort – I checked this too) do not recognize this, unless I restart the application
What could be the reason for this? And how can I make sure that my application can reconnect to that port? Are there any alternatives to using the SerialPort to handle the USB connector?
Best Answer
I found a solution that can handle plugging and unplugging a SerialPort.
First of all, it requires the use the SafeSerialPort, which allows you to dispose the serial port properly.
Second, you need to use LibUsbDotNet to detect whether a USB device is connected or disconnected. This will allow you to determine whether to connect to the device or reset the COM port.
Finally, disposing the SerialPort will makes sure it is registered by Windows in HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM, meaning that
SerialPort.GetPortNames()
can re-detect the port.After this process, you can simply reconnect to the COM port when the USB device is connected without the need to restart the application.
Full code: