serial read raspberry puertos puerto libreria leer example comunicacion python c windows winapi serial-port

python - read - Listado de puertos serie(COM) en Windows?



serial port python windows (8)

Estoy buscando una forma sólida de enumerar los puertos serie (COM) disponibles en una máquina con Windows. Hay una publicación sobre el uso de WMI , pero me gustaría algo menos específico para .NET: quiero obtener la lista de puertos en un programa de Python o C ++, sin .NET.

Actualmente sé de otros dos enfoques:

  1. Lectura de la información en la clave de registro HARDWARE//DEVICEMAP//SERIALCOMM . Esto parece una gran opción, pero ¿es robusto ? No puedo encontrar una garantía en línea o en MSDN de que esta celda de registro siempre contenga la lista completa de puertos disponibles.

  2. Intente llamar a CreateFile en COMN con N un número de 1 a algo. Esto no es lo suficientemente bueno, porque algunos puertos COM no se llaman COMN. Por ejemplo, algunos puertos COM virtuales creados se llaman CSNA0, CSNB0, etc., así que no confiaría en este método.

¿Algún otro método / ideas / experiencia para compartir?

Editar: por cierto, aquí hay una implementación simple de Python para leer los nombres de los puertos del registro:

import _winreg as winreg import itertools def enumerate_serial_ports(): """ Uses the Win32 registry to return a iterator of serial (COM) ports existing on this computer. """ path = ''HARDWARE//DEVICEMAP//SERIALCOMM'' try: key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, path) except WindowsError: raise IterationError for i in itertools.count(): try: val = winreg.EnumValue(key, i) yield (str(val[1]), str(val[0])) except EnvironmentError: break


Acabo de crear lo siguiente, basado en leer a través de la fuente C ++ a EnumSerialPorts y ver la función GetDefaultCommConfig() . Parecía el método más simple usando ANSI C simple y una única llamada API para cada posible puerto COM.

#include <stdio.h> #include <windows.h> #include <winbase.h> BOOL COM_exists( int port) { char buffer[7]; COMMCONFIG CommConfig; DWORD size; if (! (1 <= port && port <= 255)) { return FALSE; } snprintf( buffer, sizeof buffer, "COM%d", port); size = sizeof CommConfig; // COM port exists if GetDefaultCommConfig returns TRUE // or changes <size> to indicate COMMCONFIG buffer too small. return (GetDefaultCommConfig( buffer, &CommConfig, &size) || size > sizeof CommConfig); } int main() { int i; for (i = 1; i < 256; ++i) { if (COM_exists( i)) { printf( "COM%d exists/n", i); } } return 0; }


Creo que WMI es el camino a seguir, ya que es bastante fácil de poner en marcha y tiene un código mínimo. Le ahorra tener que cavar dentro del registro y le da cierta garantía de que funcionará para situaciones más generales en el futuro.

Puede instalar todo lo necesario con pip install pypiwin32 WMI y funciona de fábrica.

Código

import wmi query = "SELECT * FROM Win32_PnPEntity WHERE Name LIKE ''%(COM%)''" coms = wmi.WMI().query(query) for com in coms: print(com.Name)

Salida

Communications Port (COM1) mbed Serial Port (COM3) mbed Serial Port (COM5)

Supongo que su puerto serie es una especie de Plug ''n Play, así que debería funcionar bien. Por alguna razón, Win32_SerialPort no funciona para todos los puertos.



Esto definitivamente es bastante tarde, ¡pero fue útil para mí!

http://eli.thegreenplace.net/2009/07/31/listing-all-serial-ports-on-windows-with-python/

Particularmente este ejemplo:

import re def full_port_name(portname): """ Given a port-name (of the form COM7, COM12, CNCA0, etc.) returns a full name suitable for opening with the Serial class. """ m = re.match(''^COM(/d+)$'', portname) if m and int(m.group(1)) < 10: return portname return ''////.//' + portname



Hoy en día hay un trazador de líneas de Powershell para eso.

[System.IO.Ports.SerialPort]::GetPortNames()


Usando pySerial con Python:

import serial.tools.list_ports ports = list(serial.tools.list_ports.comports()) for p in ports: print p