Подтвердить что ты не робот

Что такое кросс-платформенный метод перечисления последовательных портов в Python (включая виртуальные порты)?

Примечание. Я использую 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?

Как я должен перечислять последовательные порты (виртуальные тоже) независимо от платформы?

Edit

Я нашел несколько актуальных вопросов:

4b9b3361

Ответ 1

Это то, что я использовал. Это mashup методов, которые я написал выше. Тем не менее, мне все же хотелось бы видеть лучшие решения.

# 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*')

Ответ 2

bitpim имел довольно много кода для comscan на нескольких платформах. Вероятно, полезно получить некоторый код оттуда для создания перекрестного перекрестного перечислителя портов. Вы можете запустить код обнаружения непосредственно в командной строке, чтобы проверить его.

Ссылка на исходный файл 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.

Интересно посмотреть раздел "Платформа" в документации для этой команды:

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

Я думаю, что объединение двух должно дать (почти) 100% надежный счетчик com-портов.

Изменить. Пробовал все вышеперечисленное в Python 2.7.

Ответ 3

Есть ли функция pyserial, serial.tools.list_ports, дает вам то, что вы хотите?

Ответ 4

Я не знаю, если вы все еще ищете ответы на это, но поскольку у меня есть рабочее решение, я думал, что опубликую его. Вот пакет для передачи в составе моего проекта Arduino Data Logger. Я протестировал его, чтобы работать на Mac, по крайней мере, несколько вариантов Linux и Windows 7. В отличие от bitpim comscan, он не использует никаких модулей не из стандартной библиотеки. Кроме того, он не использует /dev globbing на Linux или Mac, поэтому переименование правил не должно быть проблемой. (В Linux он использует sysfs, а на Mac он использует IOKit.) Я не знаю, обнаруживает ли он виртуальные последовательные порты в Linux, но если это не так, попробуйте заменить

sys_suffix = '/device/'

с

sys_suffix = ''

в linuxgetports.py