Python自动选择串口(适用于Arduino)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24214643/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 04:14:01  来源:igfitidea点击:

Python to automatically select serial ports (for Arduino)

pythonpython-2.7serial-portarduinopyserial

提问by Nyxynyx

Currently the python program must know which port a device (Arduino) is on before Python can communicate the device.

目前,python 程序必须知道设备(Arduino)在哪个端口上,Python 才能与设备通信。

Problem:Whenever the device is plugged out and back in, its COM port changes, so the correct serial port must be given to Python again for it to find the device.

问题:无论何时拔出并重新插入设备,其 COM 端口都会发生变化,因此必须再次将正确的串行端口提供给 Python 才能找到该设备。

How can Python (using pySerial) automatically search for the correct serial port to use? Is it possible for python to correctly identify the device on a serial port as an Arduino?

Python(使用pySerial)如何自动搜索要使用的正确串行端口?python是否可以将串口上的设备正确识别为Arduino?

回答by Matt Williams

Use the following code to see all the available serial ports:

使用以下代码查看所有可用的串行端口:

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

This gives me the following:

这给了我以下内容:

('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')

To work out if it's an Arduino you could do something like:

要确定它是否是 Arduino,您可以执行以下操作:

    if "Arduino" in p.description:
        print "This is an Arduino!"

回答by Joseph F. Mack

"""
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()

回答by Eric

Using serial.tools.list_ports.comports, we can find and connect to an arduino with:

使用serial.tools.list_ports.comports,我们可以找到并连接到一个 arduino:

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])

If you know you're looking for exactly the same arduino each time, you can filter on p.serial_numberinstead

如果你知道你每次找一模一样的Arduino的,你可以筛选p.serial_number代替

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

回答by Pardeep Singh

Try this code (only for windows users. MAC user can withdraw idea from this concept)

试试这个代码(仅适用于 Windows 用户。MAC 用户可以从这个概念中撤回想法)

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())