【问题标题】:What is the cross-platform method of enumerating serial ports in Python (including virtual ports)?Python中枚举串口(包括虚拟端口)的跨平台方法是什么?
【发布时间】:2012-07-03 02:51:18
【问题描述】:

注意:我使用 Python 2.7 和 pySerial 进行串行通信。

我发现这篇文章列出了两种方法:http://www.zaber.com/wiki/Software/Python#Displaying_a_list_of_available_serial_ports

此方法适用于 Windows 和 Linux,但有时会错过 Linux 上的虚拟端口:

import serial

def scan():
   # scan for available ports. return a list of tuples (num, name)
   available = []
   for i in range(256):
       try:
           s = serial.Serial(i)
           available.append( (i, s.portstr))
           s.close()
       except serial.SerialException:
           pass
   return available

print "Found ports:"
for n,s in scan(): print "(%d) %s" % (n,s)

而这个仅适用于 Linux,但包含虚拟端口:

import serial, glob

def scan():
   # scan for available ports. return a list of device names.
   return glob.glob('/dev/ttyS*') + glob.glob('/dev/ttyUSB*')

print "Found ports:"
for name in scan(): print name

我想我可以在 Linux 上运行时使用第二种方法(包括虚拟端口的方法)进行平台检测,在运行 Windows 时使用第一种方法,但是 Mac 呢?

无论平台如何,我应该如何枚举串行端口(也是虚拟的)?

编辑

我发现了一些相关的问题:

【问题讨论】:

  • 多年来我一直在做跨平台串行的东西,我总是把同一个愚蠢的平台检测、通配符、手动调整的怪物组合在一起。我很想看看你是否得到任何好的答案。
  • 好吧,我想这就是它必须要做的事情:(。有时间我会在 Linux 和 Mac 上测试它,看看我是否不能把它包装成一个图书馆。
  • 给它几天,有人可能有一个更优雅的解决方案:)
  • 只是想我会在这里添加它。 bitpim 在多个平台上有相当多的 comscan 代码。从那里获取一些代码以构建跨平台串行端口枚举器可能很有用。 bitpim.svn.sourceforge.net/viewvc/bitpim/trunk/bitpim/src/…
  • @n9986:这看起来很有希望,谢谢!你应该把它作为一个答案。

标签: python cross-platform serial-port python-2.7 pyserial


【解决方案1】:

这是我一直在使用的。这是我上面发布的方法的混搭。不过,我仍然希望看到更好的解决方案。

# A function that tries to list serial ports on most common platforms
def list_serial_ports():
    system_name = platform.system()
    if system_name == "Windows":
        # Scan for available ports.
        available = []
        for i in range(256):
            try:
                s = serial.Serial(i)
                available.append(i)
                s.close()
            except serial.SerialException:
                pass
        return available
    elif system_name == "Darwin":
        # Mac
        return glob.glob('/dev/tty*') + glob.glob('/dev/cu*')
    else:
        # Assume Linux or something else
        return glob.glob('/dev/ttyS*') + glob.glob('/dev/ttyUSB*')

【讨论】:

  • 如果平台不是 Windows,您可能想要使用 serial.tools.list_ports_posix。它支持除 OSX 和 Linux 之外的多个 Posix 平台。
  • Mac 和 Linux 的串行端口设备无论如何都不必遵循这些模式,是吗?我认为可以有 udev 规则在 /dev/ 中给他们任何名字
  • 在 OS X 上,有时会出现 '/dev/tty...' 与上述模式不匹配。例如。来自华为的 2 个不同的 USB 记忆棒调制解调器可以是 '/dev/cu.HUAWEIMobile-' 或 '/dev/tty.HUAWEIMobile-'
  • @Mu Mind 能否详细说明一下 udev 规则?
  • 您可以在 /etc/udev/rules.d/ 中添加规则文件并覆盖 NAME 字段。这是一个full example(使用SYMLINK而不是NAME),这是一个使用NAMEshorter example
【解决方案2】:

bitpim 在多个平台上有相当多的 comscan 代码。从那里获取一些代码以构建跨平台串行端口枚举器可能很有用。您可以直接在命令行中运行检测代码进行测试。

Link to source file comscan.py.

在 Linux 中,它似乎没有检测到“/dev/ttyS”端口。在 #378 行下面添加以下行:

("/dev/ttyS", "Standard Serial Port", "serial"),

作者使为串口添加不同类型的标识符变得容易。

在 Mac 中,它工作得很好。 (有一个 Arduino 方便测试)

在 Windows 中,它成功检测到连接的端口(用于连接的 FTDI 连接器)。需要pywin32

使用pyserial,我尝试了以下方法:

python -m serial.tools.list_ports

似乎不适用于 Windows。在 Mac 上工作。在 Linux 上运行。

documentation for this command中的平台部分很有趣:

Platform :  Posix (/dev files)
Platform :  Linux (/dev files, sysfs and lsusb)
Platform :  Windows (setupapi, registry)

我认为将两者结合起来应该可以提供(几乎)100% 可靠的通信端口枚举器。

编辑:在 Python 2.7 中尝试了以上所有方法。

【讨论】:

  • 感谢您发布这一切!我给了你赏金,因为我认为这是迄今为止最有希望的答案。当我(或其他人)有机会验证它时,我会接受它。
  • 谢谢!稍后我会看看是否可以为此挖掘更多信息(网络或从我的笔记中)。将在此处添加。
  • serial.tools.list_ports 在 windows 上使用 python 3.4 为我检测 FTDI 电缆。 :)
【解决方案3】:

pyserial 函数serial.tools.list_ports 是否给你想要的东西?

【讨论】:

  • 不幸的是,在 Windows 上,comports() 什么也没给我。另一方面,上面的第一种方法正确列出了我激活的(单个)端口。
  • 它似乎不适用于虚拟 USB com 端口(这基本上是新计算机的标准)
【解决方案4】:

我不知道你是否还在寻找这个问题的答案,但由于我有一个可行的解决方案,我想我会发布它。这是 the getports package 作为我的 Arduino 数据记录器项目的一部分。我已经测试过它可以在 Mac、至少某些版本的 Linux 和 Windows 7 上运行。与 bitpim 的 comscan 不同,它不使用任何非标准库中的模块。此外,它在 Linux 或 Mac 上不使用/dev globbing,因此重命名规则应该不是问题。 (在 Linux 上它使用 sysfs,在 Mac 上它使用 IOKit。)我不知道它是否检测到 Linux 上的虚拟串行端口,但如果没有,请尝试替换

sys_suffix = '/device/'

sys_suffix = ''

linuxgetports.py

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-08
    • 2021-01-28
    • 1970-01-01
    • 2011-07-25
    相关资源
    最近更新 更多