views:

47

answers:

2

I have an application which is supposed to communicate with multiple custom devices, some of which use FTDI USB-to-serial converter chips, and some of which use TCP. The application needs to be able to accept data at any time, from devices which may be plugged or unplugged at any time; the application serves as a bridge between devices and a database.

It seems that when a device is unplugged, it will often cause the SerialPort class to throw an exception in a BackgroundWorker thread and crash the application.

My present remedy, which is probably absurdly complicated, is to have a helper application send/receive serial port data and relay it to/from a TCP socket. When my main application sees that a USB device is plugged in, it launches this other application and then uses a TCP socket to communicate with it. If multiple USB devices are plugged in, a separate instance of the helper application will be launched for each. When a USB port is unplugged, the helper application will crash, but the "Unexpected shutdown" message will be stifled.

This approach works, but it seems massively unsatisfying. There's got to be a better way.

A: 

I have tested removing a USB to serial adapter while in use under .Net 4.0. It does not cause application crashes as did previous versions of .Net. Also, under previous versions, not only would the application crash, but sometimes you had to reboot to get the port to work at all.

dbasnett
What version of Windows is required for .Net 4.0? Right now I'm using 2.0, which means my apps will run under Windows 98 or 2000, though I'm not sure how many end users are still running such systems.
supercat
.NET 4.0 requires Windows XP SP3.
Rogier
A: 

I had the same problems with .NET 2.0 and I reverted to using the FTDI dll wrapper: http://www.ftdichip.com/Support/SoftwareExamples/CodeExamples/CSharp/FTD2XX_NET_1010.zip

Works very well, and you have access to control the real goodies of the driver, such as programmatically setting the latency timer.

I wrote my own class to detect unplug events, by catching the FT_IO_ERROR event, when trying to read the data. This is not entirely satisfying, by catching an error and claiming it is an unplug. But it works.

I have been talking to FTDI about this and recently they released a new application note: http://ftdichip.com/Support/Documents/AppNotes/AN_152_Detecting_USB_%20Device_Insertion_and_Removal.pdf

That uses the WM_DEVICECHANGE event to detect USB unplugs. Also works, but there is a small catch. Because it is a window message, it only works if you have a GUI and there are cases where the event will not arrive at your application, if another application is running and catches the event before you can process it.

The final option is to use WMI to do the detection.You can use the ManagementEventWatcher to create a listener on create and delete. Also got this to work, however there were some USB ports on my laptop where the FTDI driver would not give the correct COM port and location ID back (actually, just nothing at all) and that is the info which I could read from WMI, so I could not link a WMI event to the connected device in the DLL wrapper.

I reported this issue to FTDI in june/july 2010 and supposedly the GetCOMportNumber and Location ID issues are fixed in their 2.08.02 driver version (august), but I have not had the time to recheck this.

So far my experiences with the USB hell....

Rogier
@Rogier: Thanks for your reply. I'll look into that if I have time. I've been using a separate ap to handle the port connection and while the approach feels incredibly icky, it's been working well enough that there's no major impetus to change. Certainly nice to know for future projects, though.
supercat
NP. I've been wanting to write a blog post about all this somewhere for future reference of people, so I could help a bit more, but the code now is just too messy...
Rogier