pySerial serial.open()在交互式外壳中工作,但作为脚本引发异常

时间:2018-09-11 19:04:02

标签: python pyserial

编辑:似乎问题可能与Python 3有关。我尝试在Python 2.7.15的Anaconda环境中执行脚本,并使其能够正常工作。考虑到可能只是Anaconda,我尝试在Python 3.6.5的Anaconda环境中运行它,并遇到了相同的错误。为了删除Anaconda的变量,我尝试从不带Anaconda的全新安装中运行Python 2.7.15,并且再次能够使脚本正常运行。请注意,在非Anaconda Python3环境中运行时出现了我的原始问题。我认为这并不能真正解决问题,但是对于遇到同一问题的任何人来说,这都是一种解决方案。

Windows 10. Python 3.6.5

我正在尝试通过pyserial建立/打开与连接的COM端口的连接。通过cmd中启动的Python shell,我能够做到这一点,但是通过脚本运行它时会收到异常。异常链是这样的:

File "C:\Python\Python36-32\lib\site-packages\serial\serialwin32.py", line 62, in open
raise SerialException("could not open port {!r}: {!r}".format(self.portstr, ctypes.WinError()))
serial.serialutil.SerialException: could not open port 'COM8': OSError(22, 'Element not found.', None, 1168)

脚本是这样的:

import serial.tools.list_ports
import time
import sys

SERIAL_CONNECTION_ATTEMPTS = 3

ports = list(serial.tools.list_ports.comports())
bluetoothPorts = []

for p in ports:
    if 'Bluetooth' in p.description:
        bluetoothPorts.append(p)
        print("Found: ", p)

selectedPort = bluetoothPorts[0]
print("selected port: ", selectedPort.device)

ser = serial.Serial()
ser.baudrate = 9600
ser.timeout = 120
ser.port = selectedPort.device

for i in range(0, SERIAL_CONNECTION_ATTEMPTS):
    try:
        ser.open()
        time.sleep(5)
        if ser.is_open():
            break
    except:
        print(sys.exc_info())
        if i == SERIAL_CONNECTION_ATTEMPTS-1:
            print("Failed to connect. Will stop trying now.")
            exit()
        print("Failed to connect. Retrying...")    
        ser.close()
        time.sleep(5)

print(ser.read(32))        
print("Closing out now..")
ser.close()

使用交互式外壳程序的成功连接完全遵循脚本,但不使用try-except块。

我注意到的一件事是目标设备似乎可以在很短的时间内识别出连接尝试。我能够做出这样的猜测,因为目标设备有一个LED指示已建立的串行连接。当脚本运行到ser.open()时,此LED闪烁一会儿,然后快速关闭。另一方面,在交互式外壳中尝试使用ser.open()时,外壳会阻塞直到建立连接并且LED保持点亮。

请让我知道是否还有其他信息可以帮助您。

1 个答案:

答案 0 :(得分:0)

好吧,您知道蓝牙,从第一次尝试开始它就不起作用,只需尝试一下,一次,两次和三次...

def getSerialOrNone(port, conn_att):
connec_attempts = 0
ser = None
while ser is None:
    try:
        connec_attempts+=1
        print('connect attempts to %s num %d' % (port , (connec_attempts)))
        ser = serial.Serial(port, 9600,timeout=1.5, parity=serial.PARITY_NONE, 
                                stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS)
        if connec_attempts == conn_att:
                print('Serial connection error',
                                       'Failed to commect to port  ', self.port  )        
                return None
#time.sleep(2)
    except Exception as e:
            print('Serial connection error',
                                   'Error sending message "%s" to controller:\n%s' %
                               (port, e))     
return ser