Szukam prostej metody, aby wyświetlić listę wszystkich dostępnych portów COM na komputerze.
Znalazłem tę metodę, ale jest ona specyficzna dla systemu Windows: listy portów szeregowych (COM) w systemie Windows?
Używam Pythona 3 z pySerial na komputerze z systemem Windows 7.
Znalazłem w pySerial API ( http://pyserial.sourceforge.net/pyserial_api.html ) funkcję, serial.tools.list_ports.comports()
która wyświetla listę portów com (dokładnie to, czego chcę).
import serial.tools.list_ports
print(list(serial.tools.list_ports.comports()))
Ale wydaje się, że to nie działa. Kiedy moja bramka USB-COM jest podłączona do komputera (widzę COM5 w Menedżerze urządzeń), ten port COM nie znajduje się na liście zwróconej przez list_ports.comports()
. Zamiast tego dostaję tylko COM4, który wydaje się być podłączony do modemu (nie widzę go w sekcji COM i LPT Menedżera urządzeń)!
Czy wiesz, dlaczego to nie działa? Czy masz inne rozwiązanie, które nie jest specyficzne dla systemu?
comports()
że minęło ponad pięć lat od zadania tego pytania, a błąd w funkcji pySerial, który został opisany w tym pytaniu (bez dokładnych informacji o tym, jak go odtworzyć) został prawdopodobnie naprawiony. Zacznij od spróbowaniaimport serial.tools.list_ports; print([comport.device for comport in serial.tools.list_ports.comports()])
. Tylko jeśli to nie zadziała, każda z poniższych odpowiedzi będzie dla Ciebie odpowiednia.ListPortInfo
obiektów. Aby uzyskać nazwy lub inne informacje, musisz użyć atrybutów tych obiektów podczas tworzenia listy. Zobacz: pythonhosted.org/pyserial/…Odpowiedzi:
To jest kod, którego używam.
Pomyślnie przetestowano na Windows 8.1 x64, Windows 10 x64, Mac OS X 10.9.x / 10.10.x / 10.11.x i Ubuntu 14.04 / 14.10 / 15.04 / 15.10 zarówno z Pythonem 2, jak i Pythonem 3.
import sys import glob import serial def serial_ports(): """ Lists serial port names :raises EnvironmentError: On unsupported or unknown platforms :returns: A list of the serial ports available on the system """ if sys.platform.startswith('win'): ports = ['COM%s' % (i + 1) for i in range(256)] elif sys.platform.startswith('linux') or sys.platform.startswith('cygwin'): # this excludes your current terminal "/dev/tty" ports = glob.glob('/dev/tty[A-Za-z]*') elif sys.platform.startswith('darwin'): ports = glob.glob('/dev/tty.*') else: raise EnvironmentError('Unsupported platform') result = [] for port in ports: try: s = serial.Serial(port) s.close() result.append(port) except (OSError, serial.SerialException): pass return result if __name__ == '__main__': print(serial_ports())
źródło
except OSError: pass
podczas testów na OSX.serial_ports()
funkcję (i nie zgłosiłby wyjątku). Dlaczego nie używaszclose()
funkcji dostarczonej przez pyserial do odłączania portu COM?Możesz użyć:
python -c "import serial.tools.list_ports;print serial.tools.list_ports.comports()"
Filtruj według znanego portu:
python -c "import serial.tools.list_ports;print [port for port in serial.tools.list_ports.comports() if port[2] != 'n/a']"
Zobacz więcej informacji tutaj: https://pyserial.readthedocs.org/en/latest/tools.html#module-serial.tools.list_ports
źródło
('COM114', 'USB Serial Port (COM114)', 'FTDIBUS\\VID_0403+PID_6001+7&2A8DEF85&0&2\\0000')
która pozwala filtrować według PID / VID USB dostawcy, co jest dokładnie tym, o co mi chodziło.('/dev/ttyACM1', 'ttyACM1', 'USB VID:PID=0483:5752 SNR=8D7B179D5354')
Świetne rozwiązanie. Dzięki!serial.tools.list_ports.comports()
i wyjaśnił, że nie działa poprawnie na platformie pytającego. Nie dodajesz żadnych informacji, których nie było w pytaniu.Zasadniczo wspomniałem o tym w dokumentacji pyserial https://pyserial.readthedocs.io/en/latest/tools.html#module-serial.tools.list_ports
import serial.tools.list_ports ports = serial.tools.list_ports.comports() for port, desc, hwid in sorted(ports): print("{}: {} [{}]".format(port, desc, hwid))
Wynik:
COM1: Port komunikacyjny (COM1) [ACPI \ PNP0501 \ 1]
COM7: Port USB MediaTek (COM7) [USB VID: PID = 0E8D: 0003 SER = 6 LOKALIZACJA = 1-2.1]
źródło
Możliwe udoskonalenie doskonałej odpowiedzi Thomasa polega na tym, że Linux i prawdopodobnie OSX również próbują otwierać porty i zwracać tylko te, które można otworzyć. Dzieje się tak, ponieważ Linux przynajmniej wyświetla listę portów jako pliki w / dev /, które nie są do niczego podłączone. Jeśli korzystasz z terminala, / dev / tty jest terminalem, na którym pracujesz, a otwieranie i zamykanie może spowodować błąd w linii poleceń, więc glob został zaprojektowany tak, aby tego nie robić. Kod:
# ... Windows code unchanged ... elif sys.platform.startswith ('linux'): temp_list = glob.glob ('/dev/tty[A-Za-z]*') result = [] for a_port in temp_list: try: s = serial.Serial(a_port) s.close() result.append(a_port) except serial.SerialException: pass return result
Ta modyfikacja kodu Thomasa została przetestowana tylko w systemie Ubuntu 14.04.
źródło
udoskonalenie odpowiedzi moylop260 :
import serial.tools.list_ports comlist = serial.tools.list_ports.comports() connected = [] for element in comlist: connected.append(element.device) print("Connected COM ports: " + str(connected))
Zawiera listę portów, które istnieją w sprzęcie, w tym te, które są używane. O wiele więcej informacji znajduje się na liście, zgodnie z dokumentacją narzędzi
źródło
list
, a twoja cztero-wyrażeniowa konstrukcjaconnected
może być napisana znacznie bardziej zwięźle jakoconnected = [port.device for port in serial.tools.list_ports.comports()]
.rozwiązanie jednoprzewodowe z pakietem pySerial.
źródło
Spróbuj tego kodu:
import serial ports = serial.tools.list_ports.comports(include_links=False) for port in ports : print(port.device)
przede wszystkim należy zaimportować pakiet do komunikacji przez port szeregowy, więc:
import serial
następnie tworzysz listę wszystkich aktualnie dostępnych portów szeregowych:
ports = serial.tools.list_ports.comports(include_links=False)
a następnie, przechodząc przez całą listę, możesz na przykład wydrukować nazwy portów:
for port in ports : print(port.device)
To jest tylko przykład, jak pobrać listę portów i wydrukować ich nazwy, ale jest kilka innych opcji, które możesz zrobić z tymi danymi. Po prostu spróbuj wydrukować różne warianty później
źródło
Dostępnych jest kilka opcji:
Wywołaj QueryDosDevice z NULL lpDeviceName, aby wyświetlić listę wszystkich urządzeń DOS. Następnie użyj CreateFile i GetCommConfig dla każdej nazwy urządzenia, aby dowiedzieć się, czy jest to port szeregowy.
Wywołaj SetupDiGetClassDevs z ClassGuid o wartości GUID_DEVINTERFACE_COMPORT.
Usługa WMI jest również dostępna dla programów C / C ++ .
Trwa rozmowa na grupie dyskusyjnej win32 i projekcie CodeProject .
źródło
wypróbuj ten kod
import serial.tools.list_ports for i in serial.tools.list_ports.comports(): print(i)
wraca
jeśli po prostu nie chcesz nazwy portu na przykład COM1
import serial.tools.list_ports for i in serial.tools.list_ports.comports(): print(str(i).split(" ")[0])
wraca
jak w moim przypadku py 3.7 64bits
źródło
Działa tylko w systemie Windows:
import winreg import itertools def serial_ports() -> list: path = 'HARDWARE\\DEVICEMAP\\SERIALCOMM' key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, path) ports = [] for i in itertools.count(): try: ports.append(winreg.EnumValue(key, i)[1]) except EnvironmentError: break return ports if __name__ == "__main__": ports = serial_ports()
źródło