Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[all] Serialport.list Information Wrong/Missing #1220

Closed
McClellandLaboratories opened this issue Jul 5, 2017 · 20 comments · Fixed by #1266 or #1288
Closed

[all] Serialport.list Information Wrong/Missing #1220

McClellandLaboratories opened this issue Jul 5, 2017 · 20 comments · Fixed by #1266 or #1288

Comments

@McClellandLaboratories
Copy link

McClellandLaboratories commented Jul 5, 2017

  • SerialPort Version: 4.07

  • NodeJS Version: 7.1

  • Operating System and Hardware Platform: Windows 10 and Ubuntu 16.04

  • Have you checked the right version of the api docs?: Yes

  • Are you having trouble installing and you checked the Installation Special Cases docs? No

  • Are you using Electron and have you checked the Electron Docs?: No

Summary of Problem

FTDI device serial numbers are missing and manufacturers are incorrect on Windows 10.

Steps and Code to Reproduce the Issue

Using Windows 10, plug in a FTDI USB device. Next, assign it a unique USB device descriptor using FT_Prog. After programming the FTDI device with the new USB device descriptors, run serialport-list -f jsonline, resulting in output similar to the following:

{"comName":"COM23","manufacturer":"FTDI","pnpId":"FTDIBUS\\VID_0403+PID_6001+A51MAMMEA\\0000","vendorId":"0403","productId":"6001"}

Using Ubuntu 16.04, plug in the same FTDI devices. Run serialport-list -f jsonline, resulting in output similar to the following:

{"comName":"/dev/ttyUSB0","manufacturer":"MLI","serialNumber":"MLI_scale_A51MAMME","pnpId":"usb-MLI_scale_A51MAMME-if00-port0","vendorId":"0x0403","productId":"0x6001"}

Why are the manufacturers listed differently between the two operating systems. Why doesn't windows see the serialNumber? Is there any way to fix this.

@reconbot
Copy link
Member

reconbot commented Jul 6, 2017

It's been a long time since I've fully explored the apis involved but you can find the code responsible for returning the information here; https://github.com/EmergingTechnologyAdvisors/node-serialport/blob/master/src/serialport_win.cpp#L525-L573

Long story short, we ask the system for the info with SetupDiGetDeviceRegistryProperty and return it to the list function. For manufacturer we use SPDRP_MFG which is defined as

The function retrieves a REG_SZ string that contains the name of the device manufacturer.

So it's probably down to the drivers your using to load the FTDI device. Maybe FTDI has newer ones or will take a bug report?

For the serial number, I don't see that as a thing we can read from the pnp subsystem but I might be overlooking it. I do see we read some values out of the registry with RegQueryValueEx so maybe there's a way we can accomplish it with that approach.

Happy to add it if you can figure it out. Also happy to be shown references to how other serial port libraries (eg pyserial) if they include the missing info, so we can copy them.

@McClellandLaboratories
Copy link
Author

Ok so i searched through the windows registry after taking a look at :
https://github.com/EmergingTechnologyAdvisors/node-serialport/blob/master/src/serialport_win.cpp#L525-L573

On Windows 10 the USB registry files are located under: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB

This is what I see on windows:
image

Note that I have highlighted one of the folders A51MAMME. This name of the folder is the serial number for this device.

If I go to the Device Parameters folder I see the following:
image

Note the SymbolicName REG_SZ :
??\USB#VID_0403&PID_6001#A51MAMME#{a5dcbf10-6530-11d2-901f-00c04fb951ed}

It contains the VID (0403), PID (6001), and the serialnumber (A51MAMME). So it looks like the serial number is available in the registry :) So maybe we can retrieve it with RegQueryValueEx?

@McClellandLaboratories
Copy link
Author

So I installed pyserial on windows and ran their equivalent command line list and got the following:

COM23
desc: USB Serial Port (COM23)
hwid: USB VID:PID=0403:6001 SER=A51MAMMEA

So I dug into their code and it looks like they are retrieving the information from the registry using regular expressions, shown in the highlighted lines in the link below:

https://github.com/pyserial/pyserial/blob/master/serial/tools/list_ports_windows.py#L251-L257

@reconbot
Copy link
Member

reconbot commented Jul 8, 2017

I'm confused. We have quite a few results.

  • linux node-serialport: Atlas_pH_DO1KHTT8 (from this command udevadm info)
  • registry A51MAMME
  • pyserial A51MAMMEA

Is A51MAMME the expected value in all cases? What are we getting on linux?

@McClellandLaboratories
Copy link
Author

McClellandLaboratories commented Jul 10, 2017

Ok sorry for the confusion, I switched devices midway through, which was definitely confusing. I have gone back through my posts and fixed them so that the sole device discussed is the one with the serial number A51MAMME. A51MAMME is the expected value in all cases.

linux node-serialport: MLI_scale_A51MAMME
(Note: This is actually the manufacturer + _ + manufacturer description + _ + serial number)
So this isn't exactly the "serial number", but at least it contains the serial number.

registry: A51MAMME

pyserial: A51MAMMEA
(Note there is an extra "A" at the end of the serial number, the same error occurs for other FTDI devices. They all seem to have an extra "A" appended to the end of the serial number. )

So I didn't notice this before, but it looks like windows node-serialport is picking up the serial number in the pnpID. For reference here is the windows node-serialport -f -jsonline printout for the A51MAMME device:

{"comName":"COM23","manufacturer":"FTDI","pnpId":"FTDIBUS\VID_0403+PID_6001+A51MAMMEA\0000","vendorId":"0403","productId":"6001"}

Note the pnpID contains "A51MAMMEA", I am not sure why we are getting an extra "A" character at the end.

It would probably be easy enough to extract the serialNumber from windows registry or pnpID, and then return a "serialNumber" entry in the serialport-list json object. If we wanted the linux "serialNumber" and windows "serialNumber" entries to match, it would probably be best to remove the extra information stored in the linux entry (aka manufacturer, which already exists as a separate entry, and the manufacturer description (perhaps a new entry could be added for this information?)).

@reconbot
Copy link
Member

reconbot commented Jul 25, 2017

I only have an arduino uno to test with

linux

{
  "comName":"/dev/ttyACM0",
  "pnpId":"usb-Arduino__www.arduino.cc__0043_752303138333518011C1-if00",
  "productId":"0x0043",
  "serialNumber":"Arduino__www.arduino.cc__0043_752303138333518011C1",
  "manufacturer":"Arduino__www.arduino.cc_",
  "vendorId":"0x2341"
}

osx

{
  "comName":"/dev/tty.usbmodem1431",
  "manufacturer":"Arduino (www.arduino.cc)",
  "serialNumber":"752303138333518011C1",
  "locationId":"0x14300000",
  "vendorId":"0x2341",
  "productId":"0x0043"
}

windows

{
  "comName":"COM3",
  "manufacturer":"Microsoft",
  "pnpId":"USB\\VID_2341&PID_0043\\752303138333518011C1",
  "locationId":"Port_#0003.Hub_#0001",
  "vendorId":"2341",
  "productId":"0043"
}

Ideal

{
  "manufacturer":"Arduino (www.arduino.cc)",
  "serialNumber":"752303138333518011C1",  
  "vendorId":"2341",
  "productId":"0043"
}

The locationId and pnpId are not consistant, I don't know what they should be.

osx

{
  "locationId":"14300000",
  "pnpId": undefined
}

windows

{
  "locationId":"Port_#0003.Hub_#0001",
  "pnpId":"USB\\VID_2341&PID_0043\\752303138333518011C1",
}

linux

{
  "locationId": undefined,
  "pnpId":"usb-Arduino__www.arduino.cc__0043_752303138333518011C1-if00"
}

Does the ideal look correct to you? Do you have thoughts on the locationId and pnpId?

@reconbot reconbot added the macOS Mac OS X / OS X label Jul 25, 2017
@reconbot reconbot changed the title Windows 10 FTDI Information Wrong/Missing [all] Serialport.list Information Wrong/Missing Jul 25, 2017
@thiago-sylvain
Copy link

thiago-sylvain commented Jul 25, 2017

To fuel the discussion, I am also using a FTDI chip, and facing this problem.

Here is the value of the serialport object on windows:

comName: "COM29"
locationId: undefined
manufacturer: "FTDI"
pnpId: "FTDIBUS\VID_0403+PID_6015+DO008I0CA\0000"
productId: "6015"
serialNumber: undefined
vendorId: "0403"

Here is the equivalent on Linux:

comName: "/dev/ttyUSB0"
manufacturer: "FTDI"
pnpId: "usb-FTDI_FT230X_Basic_UART_DO008I0C-if00-port0"
productId: "0x6015"
serialNumber: "FTDI_FT230X_Basic_UART_DO008I0C"
vendorId: "0x0403"

The expected serial number here for me is DO008I0C.
Yes, Windows sometimes append the 'A' at the end, sometimes not, it was already the case when I was using pyserial so I coped with by using a regexp.

Pyserial seems to face the same difficulties pyserial/pyserial#61.
Libraries based on D2XX driver like https://www.npmjs.com/package/ftdi seems to work ok.

But today I faced a new behavior, while I was testing on Windows, some ports identified this way:

comName: "COM29"
locationId: undefined
manufacturer: "FTDI"
pnpId: "FTDIBUS\VID_0403+PID_6015+7&C0956A8&0&1\0000"
productId: "6015"
serialNumber: undefined
vendorId: "0403"

So here the regexp is pretty useless.
After rebooting windows, the enumeration is done correctly again.
My two cents is that the problem is related to the implementation of a low level windows driver but I don't have the skill to dig into it, so except if someone here has it, I think I am about to drop the idea of relying on the serial number to identify my devices.

@McClellandLaboratories
Copy link
Author

McClellandLaboratories commented Jul 25, 2017

@reconbot The ideal looks correct to me. It appears that windows and linux have unique pnpID formats (Ref. https://www.netiq.com/documentation/platespin-migrate-12-2/migrate-user/data/t40xx337skwt.html). I am not sure what the locationID.

@thiago-sylvain what version of Windows are you using?

@thiago-sylvain
Copy link

Windows 10, x64.

@reconbot
Copy link
Member

I spent a few hours on this today. It looks like on windows usb connected serialports the serial number is in the last bit of the pnp id.

@thiago-sylvain that means your device drivers are reporting a serial number of 0000

@frank-dspeed
Copy link
Contributor

@reconbot the A\0000 could be some kind of internal address it looks like that maybe windows uses some kind of internal addresses was facing that with cctalk devices also

reconbot added a commit that referenced this issue Jul 29, 2017
- [osx] remove the 0x from productID and locationId and vendorId
- [linux] remove the starting 0x from any values, small refactor
- [linux] Fixup output using the hex encoded fields
- [windows] Grab the serial number from the pnp id
- Isolate list functions to their own platform files (c++)
- Better ensure our serialports fields are present

closes #1220
@reconbot
Copy link
Member

Fixed serial numbers on linux and usb connected windows devices. Manufacturers are reported by windows drivers, but seem to be equal on osx and linux.

Since I now pull serialnumbers from the pnpid, I think maybe it will still be different A51MAMMEA\0000. That last slash doesn't exist among the serial devices I have. (Arduino's and FTDI devices)

@McClellandLaboratories Can you run a test of master with your device?

@McClellandLaboratories
Copy link
Author

McClellandLaboratories commented Jul 31, 2017

OK, so I tested four different devices:

Arduino Mega
(https://www.amazon.com/keyestudio-development-board-compatible-arduino/dp/B016JWNYBE)

Atlas Scientific EZO-RGB Probe
https://www.atlas-scientific.com/product_pages/probes/ezo-rgb.html
Programmed (using FTProg) USB string descriptors to:
Manufacturer: Atlas
Product Description: RGB

Gearmo FTDI2-LED USB RS-232 Serial Adapter
(https://www.amazon.com/gp/product/B01DT6K8G2/ref=oh_aui_detailpage_o07_s00?ie=UTF8&psc=1)
Programmed (using FTProg) USB string descriptors to:
Manufacturer: hamilton
Product Description: MVP4

Arducam Nano V3.0 (Arduino Nano with FTDI)
(https://www.amazon.com/Arducam-Atmega328p-Controller-Development-Compatible/dp/B01983R7PK/ref=sr_1_1?ie=UTF8&qid=1501520623&sr=8-1&keywords=ftdi+nano)
Programmed (using FTProg) USB string descriptors to:
Manufacturer: MLI
Product Description: scale

Linux

Arduino Mega
{"manufacturer":"Arduino (www.arduino.cc)","serialNumber":"85531303630351C081D2","pnpId":"usb-Arduino__www.arduino.cc__0042_85531303630351C081D2-if00","vendorId":"2341","productId":"0042","comName":"/dev/ttyACM0"}

This one is perfect, all of the information is reporting to the correct fields.

Atlas Scientific EZO-RGB Sensor
{"manufacturer":"Atlas","serialNumber":"DJ1XJE67","pnpId":"usb-Atlas_RGB_DJ1XJE67-if00-port0","vendorId":"0403","productId":"RGB","comName":"/dev/ttyUSB1"}

The only thing wrong here is the productId, which should be 6015. RGB is the product description.

Gearmo FTDI2-LED USB RS-232 Serial Adapter
{"manufacturer":"hamilton","serialNumber":"AL1WHZWF","pnpId":"usb-hamilton_MVP4_AL1WHZWF-if00-port0","vendorId":"0403","productId":"MVP4","comName":"/dev/ttyUSB0"}

The only thing wrong here is the productId, which should be 6001. MVP4 is the product description.

Arducam Nano V3.0 (Arduino Nano with FTDI)
{"manufacturer":"MLI","serialNumber":"A51MAMME","pnpId":"usb-MLI_scale_A51MAMME-if00-port0","vendorId":"0403","productId":"scale","comName":"/dev/ttyUSB2"}

The only thing wrong here is the productId, which should be 6001. scale is the product description.

Windows 10

Arduino Mega
{"comName":"COM8","manufacturer":"Arduino LLC (www.arduino.cc)","serialNumber":"85531303630351C081D2","pnpId":"USB\\\\VID_2341&PID_0042\\\\85531303630351C081D2","locationId":"Port_#0002.Hub_#0003","vendorId":"2341","productId":"0042"}

This one is perfect, all of the information is reporting to the correct fields.

Atlas Scientific EZO-RGB Sensor
{"comName":"COM5","manufacturer":"FTDI","pnpId":"FTDIBUS\\VID_0403+PID_6015+DJ1XJE67A\\0000","vendorId":"0403","productId":"6015"}

No serialNumber field is reported. The serial number for this device is DJ1XJE67.

Gearmo FTDI2-LED USB RS-232 Serial Adapter
{"comName":"COM5","manufacturer":"FTDI","pnpId":"FTDIBUS\\VID_0403+PID_6001+AL1WHZWFA\\0000","vendorId":"0403","productId":"6001"}

No serialNumber field is reported. The serial number for this device is AL1WHZWF.

Arducam Nano V3.0 (Arduino Nano with FTDI)
{"comName":"COM6","manufacturer":"FTDI","pnpId":"FTDIBUS\\VID_0403+PID_6001+A51MAMMEA\\0000","vendorId":"0403","productId":"6001"}

No serialNumber field is reported. The serial number for this device is A51MAMME.

Results Summary

The Arduino Mega data is reported correctly for Linux and Windows.

The FTDI devices had some issues. In Linux, the productID was reporting the product description instead of the PID numbers. In Windows, no serialNumber field was reported. However, the serialNumber is present in the pnpID.

Notice the difference in formatting when comparing the Windows 10 pnpIDs:

Arduino Mega
"pnpId":"USB\\VID_2341&PID_0042\\85531303630351C081D2"

Atlas Scientific EZO-RGB Sensor
"pnpId":"FTDIBUS\\VID_0403+PID_6015+DJ1XJE67A\\0000"

Gearmo FTDI2-LED USB RS-232 Serial Adapter
"pnpId":"FTDIBUS\\VID_0403+PID_6001+AL1WHZWFA\\0000",

Arducam Nano V3.0 (Arduino Nano with FTDI)
"pnpId":"FTDIBUS\\VID_0403+PID_6001+A51MAMMEA\\0000"

The Arduino Mega is not a FTDI device, which is shown first by the 'USB\\'. The VID and PID are seperated by an '&', and the serial number is separated from the serialNumber by '\\'.

In comparison, the FTDI devices are reported with a 'FTDIBUS\\'. The VID, PID, and serialNumber are seperated by '+', an 'A' is tacked on to the end of the serial number and \\0000 is added at the end.

Maybe the FTDI device information on Windows would be easiest to extract from the pnpID using a regular expression that can catch both results from normal USB devices (like the Arduino Mega) and FTDI devices.

@thiago-sylvain
Copy link

thiago-sylvain commented Aug 1, 2017

node-serialport v5.0.0 and FTDI 230X

Linux

comName: "/dev/ttyUSB0"
locationId: undefined
manufacturer: "FTDI"
pnpId: "usb-FTDI_FT230X_Basic_UART_DO004ZB7-if00-port0"
productId: "FT230X Basic UART"
serialNumber: "DO004ZB7"
vendorId: "0403"

In the productId I was rather expecting something like 0x6015.

Windows 10

comName: "COM13"
locationId: undefined
manufacturer: "FTDI"
pnpId: "FTDIBUS\VID_0403+PID_6015+DO004ZB7A\0000"
productId: "6015"
serialNumber: undefined
vendorId: "0403"

So nothing new since beta8. Concerning the bug I reported above, still no hint on how to reproduce.

@reconbot
Copy link
Member

reconbot commented Aug 7, 2017

The productId on linux issue has been fixed in #1279

The windows serialnumber... I wish I could easily test this... I guess we'll have to break it out into a testable function.

Collecting all your test data;

FTDI Device
FTDIBUS\VID_0403+PID_6015+DO004ZB7A\0000 -> DO004ZB7

Arduino Mega
USB\\VID_2341&PID_0042\\85531303630351C081D2 -> 85531303630351C081D2

Atlas Scientific EZO-RGB Sensor
FTDIBUS\\VID_0403+PID_6015+DJ1XJE67A\\0000 -> DJ1XJE67

Gearmo FTDI2-LED USB RS-232 Serial Adapter
FTDIBUS\\VID_0403+PID_6001+AL1WHZWFA\\0000 -> AL1WHZWF

Arducam Nano V3.0 (Arduino Nano with FTDI)
FTDIBUS\\VID_0403+PID_6001+A51MAMMEA\\0000 -> A51MAMME

reconbot added a commit that referenced this issue Aug 7, 2017
This should give us more serial numbers on windows.

fixes #1220
@reconbot
Copy link
Member

reconbot commented Aug 7, 2017

Well FTDIBUS was pretty easy to sus out, the latest master is available for you perusal. If you have any other kind of devices now's the time to break them out. =)

@reconbot reconbot reopened this Aug 7, 2017
reconbot added a commit that referenced this issue Aug 7, 2017
### Bug Fixes

* **linux:** The productID should be a number not a description string ([#1279](#1279)) ([bf46f68](bf46f68))
* **tests:** fixup for [#1279](#1279) ([#1285](#1285)) ([56074f6](56074f6))
* **windows:** Add option to disable RTS ([#1277](#1277)) ([5b8d163](5b8d163))
* **windows:** Parse more types of pnpIds ([#1288](#1288)) ([0b554d7](0b554d7)), closes [#1220](#1220)


### Chores

* **binaries:** Lets switch to prebuild! ([#1282](#1282)) ([8c36e99](8c36e99))


### Features

* **test:** tone down codecov comments ([#1289](#1289)) ([749ffac](749ffac))


### BREAKING CHANGES

* **binaries:** I'm considering the switch to `prebuild` a breaking change because it's substantially changes our install processes. It's also possible the install flags to ensure downloading or building from source has changed slightly. That's not our api per say, but it's enough.
* **windows:** We previously hard coded to have RTS on for windows at all times it now default to off.
@McClellandLaboratories
Copy link
Author

Awesome job on the update! I have tried all of the devices I have, and everything looks great. Both Linux and Windows report the same "serialNumber".

One question somewhat unrelated to this issue, but why does the serialport-list in Linux show a bunch of blank com ports (as shown below):

{"manufacturer":"Arduino (www.arduino.cc)","serialNumber":"9563533373035191F0D2","pnpId":"usb-Arduino__www.arduino.cc__0042_9563533373035191F0D2-if00","vendorId":"2341","productId":"0042","comName":"/dev/ttyACM0"}
{"vendorId":"8086","productId":"a127","comName":"/dev/ttyS4"}
{"comName":"/dev/ttyS0"}
{"comName":"/dev/ttyS1"}
{"comName":"/dev/ttyS10"}
{"comName":"/dev/ttyS11"}
{"comName":"/dev/ttyS12"}
{"comName":"/dev/ttyS13"}
{"comName":"/dev/ttyS14"}
{"comName":"/dev/ttyS15"}
{"comName":"/dev/ttyS16"}
{"comName":"/dev/ttyS17"}
{"comName":"/dev/ttyS18"}
{"comName":"/dev/ttyS19"}
{"comName":"/dev/ttyS2"}
{"comName":"/dev/ttyS20"}
{"comName":"/dev/ttyS21"}
{"comName":"/dev/ttyS22"}
{"comName":"/dev/ttyS23"}
{"comName":"/dev/ttyS24"}
{"comName":"/dev/ttyS25"}
{"comName":"/dev/ttyS26"}
{"comName":"/dev/ttyS27"}
{"comName":"/dev/ttyS28"}
{"comName":"/dev/ttyS29"}
{"comName":"/dev/ttyS3"}
{"comName":"/dev/ttyS30"}
{"comName":"/dev/ttyS31"}
{"comName":"/dev/ttyS5"}
{"comName":"/dev/ttyS6"}
{"comName":"/dev/ttyS7"}
{"comName":"/dev/ttyS8"}
{"comName":"/dev/ttyS9"}

@reconbot
Copy link
Member

reconbot commented Aug 9, 2017

Yay!

Because linux doesn't differentiate between tty's and serialports in general. Do you know a way?

@reconbot reconbot closed this as completed Aug 9, 2017
@McClellandLaboratories
Copy link
Author

I wonder if filtering just based on the presence of a VID or product PID would work. Note in the above list the:

{"vendorId":"8086","productId":"a127","comName":"/dev/ttyS4"} represents a USB hub
The remaining tty's are empty, and do not contain a PID or VID.

I suppose another option would be to add a flag to serialport-list like -vidReq.

Command:
serialport-list -f jsonline -vidReq

Output:
{"manufacturer":"Arduino (www.arduino.cc)","serialNumber":"9563533373035191F0D2","pnpId":"usb-Arduino__www.arduino.cc__0042_9563533373035191F0D2-if00","vendorId":"2341","productId":"0042","comName":"/dev/ttyACM0"}
{"vendorId":"8086","productId":"a127","comName":"/dev/ttyS4"}

Anyways these are just thoughts.

@reconbot
Copy link
Member

I'm not sure how to confirm this will always be the case but I'm up for filtering it in our api. I wonder what python or tcl does...

@lock lock bot locked and limited conversation to collaborators Feb 6, 2018
reconbot added a commit that referenced this issue Jul 24, 2018
- [osx] remove the 0x from productID and locationId and vendorId
- [linux] remove the starting 0x from any values, small refactor
- [linux] Fixup output using the hex encoded fields
- [windows] Grab the serial number from the pnp id
- Isolate list functions to their own platform files (c++)
- Better ensure our serialports fields are present

closes #1220
reconbot added a commit that referenced this issue Jul 24, 2018
This should give us more serial numbers on windows.

fixes #1220
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
3 participants