pySerial list_port准确性

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了pySerial list_port准确性相关的知识,希望对你有一定的参考价值。

我想使用pySerial的serial.tools.list_ports.comports()列出可用的COM端口。

阅读documentation

该函数返回一个迭代,产生三个字符串的元组:

  • 端口名称,因为它可以传递给serial.Serial或serial.serial_for_url()
  • 人类可读形式的描述
  • 一种硬件ID。例如。可能包含VID:USB串行适配器的PID。

我特别感兴趣的是第三个字符串,用于搜索具有VID:PID对的特定USB串行适配器。我希望它(理想情况下)能够在Windows XP及更高版本,Mac OS X和Linux中运行。我在Ubuntu 13.10和Windows 7中尝试过使用pySerial 2.7并且像魅力一样,但是文档也说:

另请注意,报告的字符串在平台和操作系统之间是不同的,即使对于同一设备也是如此。

注意:支持仅限于许多操作系统。在某些系统上,描述和硬件ID将不可用。

您是否有尊重这些含糊之处的实际经验?更详细的信息?任何非工作的例子?跨系统的硬件ID字符串的变化?

非常感谢!

答案

我想如果你想要一个反例的工作方式不符合预期,这就是我得到的:

>>> serial.tools.list_ports.comports()
[('/dev/tty.Bluetooth-Incoming-Port', '/dev/tty.Bluetooth-Incoming-Port', '/dev/tty.Bluetooth-Incoming-Port'), ('/dev/tty.Bluetooth-Modem', '/dev/tty.Bluetooth-Modem', '/dev/tty.Bluetooth-Modem'), ('/dev/tty.usbserial-A1024XBO', '/dev/tty.usbserial-A1024XBO', '/dev/tty.usbserial-A1024XBO')]

插入FTDI USB串行适配器的地方。这是可以预料的,因为这里是comports()功能:

def comports():
    """scan for available ports. return a list of device names."""
    devices = glob.glob('/dev/tty.*')
    return [(d, d, d) for d in devices]

这与cygwin,BSD,NetBSD,IRIX,HP-UX,Solaris / SunOS,AIX相同......

怎么会发生这种结果?好吧,因为我的pyserial版本是2.6,只有六个月了:-)

从pypi升级到最新版本(2.7)之后,我得到的是:

>>> serial.tools.list_ports.comports()
[['/dev/cu.Bluetooth-Incoming-Port', 'n/a', 'n/a'], ['/dev/cu.Bluetooth-Modem', 'n/a', 'n/a'], ['/dev/cu.usbserial-A1024XBO', 'FT232R USB UART', 'USB VID:PID=403:6001 SNR=A1024XBO']]

所以基本上,在你的setup.py中添加版本检查到最新版本的pyserial,否则你可能会遇到问题。虽然还没有为其他unix口味添加支持。看起来VID:PID字符串是通过解析OS特定的东西来直接处理的,以使该字符串足够通用。所以基本上我猜你可以安全地得到它像:vid, pid = sp[2].split(' ')[1].split('=')[-1].split(':')(这是非常愚蠢的,为什么解析值来构建一个必须在之后再次解析的字符串?!,我的意思是他们做szHardwareID_str = 'USB VID:PID=%s:%s SNR=%s' % (m.group(1), m.group(2), m.group(4))我们不能更快乐只是一个元组!)

最后,pyserial看起来与它的文档不一致,因为它说:On some systems description and hardware ID will not be available (None).,而它确实返回'n/a'。我猜这将在pyserial 2.8中修复:-)

另一答案

从我原来的问题开始已经有一段时间了,但目前版本的pyserial(3.0+,我相信)已经以一种巧妙的方式解决了这个问题。没有更聪明的解析。

serial.tools.list_ports.comports(...)现在返回一个包含ListPortInfo对象的列表。

ListPortInfo对象包含vidpid属性(整数)以及其他有用的USB相关属性(请参阅docs)“如果它不是USB设备(或平台不支持扩展信息),它们都是None”,这似乎在主要的3个平台上得到支持(“在Linux,OSX和Windows下,扩展信息将可用于USB设备”)。

所以你可以做类似以下的事情:

for port in serial.tools.list_ports.comports():
    if port.vid is not None and port.pid is not None:
        # It's a USB port on a platform that supports the extended info
        # Do something with it.
        print("Port={},VID={:#06x},PID={:#06x}".format(port.device, port.vid, port.pid))

以上是关于pySerial list_port准确性的主要内容,如果未能解决你的问题,请参考以下文章

pyserial在检测list_ports速度过慢的解决方案

python的pyserial模块

pySerial 运行命令列出端口

python的pyserial读取串口占用状态?

关于python文件名慎取的案例

准确的pyserial读取周期