Did you know each Arduino has a unique serial number in its USB interface that you can use to distinguish one Arduino from another? If you deal with multiple Arduinos, knowing exactly which one is plugged into your computer can be a real time-saver. But actually getting at this serial number and mapping it to COM ports can be challenging.
For Windows computers, here’s “listComPorts”, implemented both in GCC C code and in VBScript, both available from my usbSearch github repository.
It gives the COM port number, the manufacturer name, the USB Vendor ID and Product ID (VID & PID) and the serial number. The result is a concatenation of the VID, PID, and serial number that Windows calls a “PnPDeviceID”. You can use the whole thing, or pick off the parts you need using simple string processing libraries. In the example above, the Arduino Diecimila has a VID/PID pair of 0403/6001 and the Teensy has a VID/PID of 16C0/0483.
Arduino Serial Numbers
In the above example, the Arduino Diecimila (which has an FTDI chip) has the serial number with a “+”-sign after the PID. So, the serial number is “A6004CCF”. The Teensy can have a programmable serial number and by default it’s set to “12345”.
With Arduino UNOs and future Arduinos, the Arduino team has their own VID/PID pair, which let’s them assign different PIDs for different classes of Arduinos. The UNO also has a much longer unique serial number than older Arduinos using the FTDI chip.
Here’s an example with two Arduino UNOs:
The serial numbers are separated by the VID/PID pair with a backslash. So my two UNOs have the serial numbers “64936333936351408161” and “6493234373835191F1F1”. Using this info, I can be sure exactly which Arduino I’m dealing with.
How it works
The C and the VBS versions both utilize the WMI infrastructure that’s been around since Windows 2000 to query the machine about its configured PnP devices. The WMI is a huge data structure of just about any information in Windows. Except, it seems, good information about COM ports. While there is a “Win32_SerialPort” table in WMI, that only contains information about hardware serial ports, not USB-to-serial adapters. Instead, these two tools look at the “Win32_PnPEntity” table. While this table does list USB-to-serial adapters, it does not contain a proper mapping of the adapter’s USB or PnP ID to COM port. Instead, these tools do a string search on the “Caption” field for the string “(COMn)” where “n” is a number. It’s an incredible hack but seems to work.
Other operating systems
On Mac OS X and pre-UNO Arduinos, knowing exactly which Arduino you were dealing with was easy because the FTDI driver put its serial number as part of the name of the serial port. For example, the port name created by the FTDI driver was “
/dev/tty.usbserial-A6004ccf” and the serial number was “A6004ccf”.
With the UNO, the Arduino team used a reprogrammable ATmega8/16u USB chip using standard CDC USB-to-serial interface, which all OSes support natively. Unfortunately, on Mac OS X, the OS’s CDC driver creates a serial port for the UNO based on USB port location, not Arduino serial number.
Thus where you plug in the UNO into determines its serial port name. For instance, on my Mac, plugging in an UNO with serial number “64936333936351408161” gives a serial port with the name of either “
/dev/tty.usbmodemfd131” or “
/dev/tty.usbmodemfa141” depending on which USB jack is used. Even if you plug in a different UNO in the same jack, you’ll get the same serial port name. This is useful for some applications, but not if you need to know exactly which UNO you’re dealing with.
For Mac OS X, I use a tool I wrote called listArduinos.pl. It tries to determine the serial port names of every Arduino Uno. It’s out looks like:
bokbok% ./listArduinos.pl Finding Arduino UNOs... /dev/tty.usbmodemfd131 - 0x2341/0x0001 - 6493234373835191F1F1 /dev/tty.usbmodemfa141 - 0x2341/0x0001 - 64936333936351400000 Found 2 Arduino UNOs bokbok%