目前,Python程序必须知道设备(Arduino)所在的端口,才能与该设备通信。
问题:每当设备被拔出并重新插入时,其COM端口会发生变化,因此必须再次将正确的串行端口提供给Python以便找到设备。
如何让Python(使用pySerial
)自动搜索要使用的正确串行端口?Python是否可以正确地将位于串行端口上的设备识别为Arduino?
目前,Python程序必须知道设备(Arduino)所在的端口,才能与该设备通信。
问题:每当设备被拔出并重新插入时,其COM端口会发生变化,因此必须再次将正确的串行端口提供给Python以便找到设备。
如何让Python(使用pySerial
)自动搜索要使用的正确串行端口?Python是否可以正确地将位于串行端口上的设备识别为Arduino?
使用以下代码查看所有可用的串行端口:
import serial.tools.list_ports
ports = list(serial.tools.list_ports.comports())
for p in ports:
print p
这给我带来了以下结果:
('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')
要确定它是否是Arduino,您可以执行以下操作:
if "Arduino" in p.description:
print "This is an Arduino!"
p.description
中。相反,p.manufacturer
包含“Arduino”,而p.serial_number
告诉我哪个是哪个 :-) - AstroFloydserial.tools.list_ports.grep('Arduino')
来过滤掉不需要的设备。你可以通过字符串或正则表达式进行搜索 https://pyserial.readthedocs.io/en/latest/tools.html#serial.tools.list_ports.grep - Jonathan Holvey使用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])
如果你知道每次都在寻找完全相同的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')
"""
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()
int<n>
不是一个合理的变量名,而8和9是非常神奇的数字。 - Eric尝试这段代码(仅适用于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())