Go Down

Topic: Getting SerialPort name of Arduino device in C# (Read 16528 times) previous topic - next topic

11tomi12

Hello!

I am trying to get the port(COM3, COM14 etc.) of a connected arduino device in my C# program.

I tried using this(link) method, but it returned null.

I posted the same question on stackoverflow and received this answer:
Quote
You need the name of the device in the driver. Depending on the driver some have names (and also serial number of device) while others do not.
I am not sure if this is the issue or not, but I have no clue how I could resolve this issue. Hope you guys can help me out! 

scottbnoob

Hi

If your port is not named it will be Null.

SerialPort sp = new SerialPort();
String portName = com.Text; // usually "COM3" for my arduino
sp.PortName = portName;
sp.BaudRate = 9600;

and then:
sp.open();
sp.write()
etc

basically you have to give it a name(ie sp.PortName = portName;) before you can get that name.




scottbnoob

Or....

Code: [Select]

ManagementObjectSearcher manObjSearch = new ManagementObjectSearcher("Select * from Win32_SerialPort");
            ManagementObjectCollection manObjReturn = manObjSearch.Get();

            foreach (ManagementObject manObj in manObjReturn)
            {               
                String portName = manObj["Name"].ToString();
                sp.PortName = portName;
            }



You will need the to include system.managment dll

Adapted from a reply here: http://stackoverflow.com/questions/12813151/how-can-i-discover-if-a-device-is-connected-to-a-specific-serial-com-port

I check and it works...

GrooverFromHolland

#3
Feb 11, 2017, 10:42 am Last Edit: Feb 11, 2017, 11:34 am by GrooverFromHolland Reason: Added Github link
hi,

I have written a Windows forms program in Visual studio 2015 Community that lists all devices with serial capabilities, like serial ports, arduino boards, USB-to serial converters, Bluetooth serial, virtual ports, etc. in a listbox.
There is also a Button that closes previous selected and opens selected port.

In my program my Arduino NANO clone shows as: USB-SERIAL CH340:COM6 and my Bluetooth LE device as:[BLE05]:COM14

Here is a Dropbox link to download the solution:

https://www.dropbox.com/sh/qxhp0l0hnle6mv4/AABeW905-6rWyFa92vho_kg8a?dl=0:

Also on Github:
https://github.com/GrooverFromHolland/GetPortnamesExample

You can use it in your own program or change it as You wish.

If You do not have Visual studio 2015,  You can browse the files and copy code in Your own code editor.

The example is spiked with comments so beginners can understand what is going on.
Greets,

Groover

jaholmes

I've never seen SerialPort.GetPortNames() return an empty list when an Arduino is plugged into my (or any other) computer.  That reeks of a driver issue, a bad cable, or some other un-good thing.

I'll take this opportunity to mention that the .NET SerialPort class is buggy as all hell, and one of the reasons I prefer... *cough* clone *cough* boards (like the Waveshare Uno Plus) with FT232s on them for applications where the Arduino is paired with a Windows app.  Then you can use FTDI's FT_PROG tool to flash a name onto your Arduino, and use their D2XX API (which has a nice C# wrapper available) to open the device by name.  No legacy serial headaches!

But if you're determined to go the legacy serial route, I'd vote for one of the following options:
1) Do SerialPort.GetPortNames() (which should work fine unless something's messed up) and just use the result to populate a drop-down menu.  Then allow the user to pick the COM port.  Any mistakes are on them at that point. :)
2) OR...  Devise a data stream format that includes an identifier for your device.  Open and read a little from each of the COM ports returned by GetPortNames(), looking for your identifier.  Optionally have a brief conversation with your device to prove you've found it.

SerialPort is a major reliability headache, though.  Things like surprise-removing your device while SerialPort is reading it will damage the internal state of the object in ways that you, the consumer, can't detect (the non-managed stream object gets freed), and afterwards you're holding a ticking time bomb.  The most common symptom is that your app crashes on close because the garbage collector tries to re-free the stream (this issue has been know for years and not fixed by Microsoft).  There are all kinds of embarrassing workarounds, like calling GC.SuppressFinalize() on the stream members, which seems to work...mostly.  But again, I find that the reliable thing is just to avoid legacy COM altogether.  The AVR USB is great for debugging, but it becomes onerous after that.  IMO.


PaulS

Quote
I'll take this opportunity to mention that the .NET SerialPort class is buggy as all hell
You have some proof of that? I have NEVER had an issue with it. I do a LOT of network apps at work and at home.

jaholmes

You have some proof of that? I have NEVER had an issue with it. I do a LOT of network apps at work and at home.
Yeah.  The most obnoxious of these are (IMO) the IOException-on-Close() bug, and the ObjectDisposedException bug. Both are blogged about extensively and widely reported on many forums, including Microsoft's own forums.  Here are a couple of useful blogs with suggested workarounds:
http://zachsaw.blogspot.com/2010/07/net-serialport-woes.html
http://zachsaw.blogspot.com/2010/07/serialport-ioexception-workaround-in-c.html

The latter is also widely reported (citation: Google results for SerialPort + ObjectDisposedException)

Here's a useful thread on the MSDN forums that goes into a workaround for that one (the GC.SuppressFinalize() workaround is one of the most popular, though I've found it's still less than 100% successful at rejecting uncatchable exceptions due to surprise removals):
https://social.msdn.microsoft.com/Forums/en-US/0e4894cd-76db-4101-8cfc-7b7f13c1489a/serialport-objectdisposedexception?forum=netfxbcl

Here's a good blog with some suggestions for a number of other SerialPort bugs/design flaws, although the thrust of the blog is really, "stay away from this class":
http://www.sparxeng.com/blog/software/must-use-net-system-io-ports-serialport

Not exactly encouraging!

So there are a few.  Other sharp edges include the need to sleep between Close() and Open() on the same object or with the same port, and the fact that calling Close() from a UI thread on shutdown can lead to a deadlock.  The former is actually called out in the documentation, although it's embarrassing vague: 
Quote from: Microsoft
"The best practice for any application is to wait for some amount of time after calling the Close method before attempting to call the Open method, as the port may not be closed instantly."
(Not surprisingly, when you look at SerialPort code others have written, you'll see that everybody picks a different amount of time. :smiley-yell:)

In short:  It's difficult to use SerialPort well, and even using it well doesn't guarantee success.  There are reliability issues that require the consumer to implement silly workarounds like inhibiting garbage collection.  They haven't been fixed by Microsoft, nor have any of the workarounds been officially blessed (as far as I can tell).  Mostly I suspect Microsoft just doesn't have a lot of time to devote to improving legacy serial support.

After wrestling with the above issues, as well as wrestling with the general annoyance of having my Windows app try to figure out what COM port my Arduino was plugged into, I realized that wresting with legacy serial just wasn't necessary.  It's so easy not to, in fact.  Just get any clone with an FT232 on it and use the D2XX C# wrapper FTDI provides.  Then you can flash proper names/descriptions onto your devices and enumerate/open them by name.  After you've gone there, you'll never want to mess with SerialPort and its myriad headaches again.

Go Up