Click here to Skip to main content
Click here to Skip to main content

Tagged as

Go to top

Select a USB Serial Device via its VID/PID

, 20 Mar 2012
Rate this:
Please Sign up or sign in to vote.
How to select a USB serial device via its VID/PID.

Introduction

I  needed to write an application that interacted with an Arduino board via its COM port. The lazy way is to display a list of all known comports and get the user to select the correct one.  It's about time for a better way. 

Background

Most USB serial port devices have unique hardware ID's, so as you plug in more serial devices, each device is then allocated a unique COM port number.

My approach is to compile an array of all COM port numbers that were historically allocated to a particular VID/PID combination. 

From there it is simple to compare the list of COM ports open now to the list of comports that were allocated to the VID/PID. The intersection of the 2 lists is the COM port desired. 

How to find the VID and PID numbers

The information you need is located in the Device Manager, sometimes in more than one place. Note that the device must be plugged in to make it visible.

Open the device manager and expand the list of COM ports. Here's what I see on my machine when the Arduino board is plugged in.

Select the port of interest, in this case COM8, right click and select Properties. A dialog box pops up, select the Details tab and Hardware ID's property. The VID and PID are displayed.

Make a note of the 4 digit numbers of interest, in this case VID is 0403, PID is 6001.

Using the code 

My initial attempt used WMI and Win32 classes, but I was not able to find the information needed. Instead I turned to the Registry. I know that this is not a 100% .NET solution, but will work for the vast majority of .NET users out there.

The function below drills down though the relevant part of the registry and filters out values with the desired VID and PID values.

Note the use of Regular Expressions. That's because Registry key formats are inconsistent. I am looking for a key in the format VID_XXXX<separator>PID_XXXX, where XXXX are 4 hex digits and <separator> is (any) single character. By examining the registry via RegEdit you'll see uppercase, lowercase or a mixture of both. <separator> may be a '+' or a '&'.

Regular Expressions makes the comparison much simpler and reliable.

Caveat Emptor 

This method returns a list of ALL serial devices with that VID/PID combination currently plugged in. That will be a problem if you have more than 1 device from the same manufacturer in use at the same time.

/// <summary>
/// Compile an array of COM port names associated with given VID and PID
/// </summary>
/// <param name="VID"></param>
/// <param name="PID"></param>
/// <returns></returns>
List<string> ComPortNames(String VID, String PID)
{
    String pattern = String.Format("^VID_{0}.PID_{1}", VID,PID);
    Regex _rx = new Regex(pattern, RegexOptions.IgnoreCase);
    List<string> comports = new List<string>();
    RegistryKey rk1 = Registry.LocalMachine;
    RegistryKey rk2 = rk1.OpenSubKey("SYSTEM\\CurrentControlSet\\Enum");
    foreach (String s3 in rk2.GetSubKeyNames())
    {
        RegistryKey rk3 = rk2.OpenSubKey(s3);
            foreach (String s in rk3.GetSubKeyNames())
            {             
             if (_rx.Match(s).Success)
             {
                RegistryKey rk4 = rk3.OpenSubKey(s);
                foreach (String s2 in rk4.GetSubKeyNames())
                {
                    RegistryKey rk5 = rk4.OpenSubKey(s2);
                    RegistryKey rk6 = rk5.OpenSubKey("Device Parameters");
                    comports.Add((string)rk6.GetValue("PortName"));
                }
            }
        }
    }
    return comports;
} 

A simple test takes the compiled list and compares it against COM ports open at this time.

static void Main(string[] args)
{
    List<string> names = ComPortNames("0403", "6001");
    if (names.Count > 0)
    {
        foreach (String s in SerialPort.GetPortNames())
        {
            if (names.Contains(s))
                Console.WriteLine("My Arduino port is " + s);
        }
    }
    else
        Console.WriteLine("No COM ports found");
}

History

  • 3/17/2012: Original version.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

dhenry_il
Software Developer (Senior) Zickel Engineering
Israel Israel
No Biography provided

Comments and Discussions

 
GeneralFor those who prefer Visual Basic (VB) PinmemberAfterHoursEngineer27-May-14 10:19 
QuestionUsing this in VB? PinmemberKyrLon10-Jul-13 4:10 
QuestionRecognizing USB Serial Port C# Pinmembersilvio pontes27-Apr-12 16:08 
AnswerRe: Recognizing USB Serial Port C# PinmemberVlad_On9-Jul-12 17:41 
You have to check the VID,PID of the USB converter and then find the COM port number associated with it.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140916.1 | Last Updated 20 Mar 2012
Article Copyright 2012 by dhenry_il
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid