Python para seleccionar automáticamente los puertos serie (para Arduino)

Actualmente, el progtwig de Python debe saber en qué puerto está conectado un dispositivo (Arduino) antes de que Python pueda comunicar el dispositivo.

Problema: cada vez que se conecta y se vuelve a conectar el dispositivo, su puerto COM cambia, por lo que se debe proporcionar a Python el puerto serie correcto para que encuentre el dispositivo.

¿Cómo puede Python (usar pySerial ) buscar automáticamente el puerto serie correcto para usar? ¿Es posible que Python identifique correctamente el dispositivo en un puerto serie como un Arduino?

Utilice el siguiente código para ver todos los puertos serie disponibles:

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

Esto me da lo siguiente:

 ('COM4', 'Arduino Due Programming Port (COM4)', 'USB VID:PID=2341:003D SNR=75330303035351300230') ('COM11', 'RS-232 Port (COM11)', 'FTDIBUS\\VID_0856+PID_AC27+BBOPYNPPA\\0000') 

Para saber si es un Arduino, podrías hacer algo como:

  if "Arduino" in p[1]: print "This is an Arduino!" 

Usando serial.tools.list_ports.comports , podemos encontrar y conectarnos a un arduino con:

 import warnings import serial import serial.tools.list_ports arduino_ports = [ p.device for p in serial.tools.list_ports.comports() if 'Arduino' in p.description # may need tweaking to match new arduinos ] if not arduino_ports: raise IOError("No Arduino found") if len(arduino_ports) > 1: warnings.warn('Multiple Arduinos found - using the first') ser = serial.Serial(arduino_ports[0]) 

Si sabe que está buscando exactamente el mismo arduino cada vez, puede filtrar en p.serial_number en p.serial_number lugar

 import serial.tools.list_ports def find_arduino(serial_number): for pinfo in serial.tools.list_ports.comports(): if pinfo.serial_number == serial_number: return serial.Serial(pinfo.device) raise IOError("Could not find an arduino - is it plugged in?") ser = find_arduino(serial_number='85430353531351B09121') 
 """ Written on a Windows 10 Computer, Python 2.7.9 Version. This program automatically detects and lists ports. If no ports are found, it simply shells out. In the printout below "list(serial.tools.list_ports.comports())" finds two ports and the program lists them out - a listout shown below: COM5 - USB-SERIAL CH340 (COM5) Found Arduino Uno on COM5 COM4 - Microsoft USB GPS Port (COM4) As each port is found, "CH340," (the name of the Adruino Uno) is searched for in the listed port with the "while int1 < 9:" loop. The first "If" statement looks for "CH340" and when found the integer value "int1" will be the same as the com port #. With a concatination, the operation "str1 = "COM" + str2" gives the com port name of the Adruino, eg. "COM5." The next "IF" statement looks for both "CH340" AND str1, ("COM5") in the above case. The statement "Found Arduino Uno on COM5" prints out, and "str1" is used in setting up the com port: ser = serial.Serial(str1, 9600, timeout=10) This program goes on to open the com port and prints data from the Adruino. The modules "serial, sys, time, serial.tools.list_ports" must all be imported. Written by Joseph F. Mack 01/29/2016. "A BIG Thank you" to all the individuals whose programs I "borrowed" from that are available in the many forums for Python and PYGame users! """ import serial import sys import time import serial.tools.list_ports serPort = "" int1 = 0 str1 = "" str2 = "" # Find Live Ports ports = list(serial.tools.list_ports.comports()) for p in ports: print p # This causes each port's information to be printed out. # To search this p data, use p[1]. while int1 < 9: # Loop checks "COM0" to "COM8" for Adruino Port Info. if "CH340" in p[1]: # Looks for "CH340" in P[1]. str2 = str(int1) # Converts an Integer to a String, allowing: str1 = "COM" + str2 # add the strings together. if "CH340" in p[1] and str1 in p[1]: # Looks for "CH340" and "COM#" print "Found Arduino Uno on " + str1 int1 = 9 # Causes loop to end. if int1 == 8: print "UNO not found!" sys.exit() # Terminates Script. int1 = int1 + 1 time.sleep(5) # Gives user 5 seconds to view Port information -- can be changed/removed. # Set Port ser = serial.Serial(str1, 9600, timeout=10) # Put in your speed and timeout value. # This begins the opening and printout of data from the Adruino. ser.close() # In case the port is already open this closes it. ser.open() # Reopen the port. ser.flushInput() ser.flushOutput() int1 = 0 str1 = "" str2 = "" while int1==0: if "\n" not in str1: # concatinates string on one line till a line feed "\n" str2 = ser.readline() # is found, then prints the line. str1 += str2 print(str1) str1="" time.sleep(.1) print 'serial closed' ser.close() 

Pruebe este código (solo para usuarios de Windows. El usuario de MAC puede retirar la idea de este concepto)

 import serial import time list=['COM1','COM2','COM3','COM4','COM5','COM6','COM7','COM8','COM9','COM10','COM11','COM12','COM13','COM14','COM15','COM16','COM17','COM18',] COM1='COM1' COM2='COM2' COM3='COM3' COM4='COM4' COM5='COM5' COM6='COM6' COM7='COM7' COM8='COM8' COM9='COM9' COM10='COM10' COM11='COM11' COM12='COM12' COM13='COM13' COM14='COM14' COM15='COM15' COM16='COM16' COM17='COM17' COM18='COM18' COM19='COM19' time.sleep(1) ser = serial.Serial() ser.baudrate = 9600 i=1 while True: time.sleep(.2) print(i) ser.port = list[i] try: ser.open() if ser.isOpen()==True: print('connected') #print('arduino is on COMPORT'.join(i)) break break except: print('waiting') i=i+1 if i==18: print('Kindly remove usb cable and try again') break print('here we go') while True: print(ser.readline())