串行连接中断时,“在处理以上异常期间,发生另一个异常”的无限循环

问题描述 投票:0回答:1

我有一个Arduino,可以使用pySerialTransfer库通过串行与我的Mac正常通信,运行了几个小时。然后是某种形式的串行中断-尽管一夜之间我无法确定原因,但只要从笔记本电脑上拔下Arduino USB电缆,我就可以很轻松地重现该行为。我的笔记本电脑上的python代码继续运行,但进入此无限错误循环:

Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/pySerialTransfer/pySerialTransfer.py", line 257, in send
    self.connection.write(stack)
  File "/usr/local/lib/python3.7/site-packages/serial/serialposix.py", line 571, in write
    raise SerialException('write failed: {}'.format(e))
serial.serialutil.SerialException: write failed: [Errno 6] Device not configured
SENT (12 byte struct): (0, -55.836434114277004, 31.732435543849192)
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/serial/serialposix.py", line 537, in write
    n = os.write(self.fd, d)
OSError: [Errno 6] Device not configured

During handling of the above exception, another exception occurred:

我似乎无法使用python代码中的任何try /除了块来捕获异常,因此我可以检测到该异常并重新启动或尝试重新连接。以下是我当前的python代码-感谢任何提示!谢谢。

#!/usr/bin/python3

import sys
import time

import arduino
import messageboard

VERBOSE = arduino.VERBOSE
SN = '75835343130351802272'  # arduino uno serial

SIMULATE_ARDUINO = arduino.SIMULATE_ARDUINO
if '-s' in sys.argv:
  SIMULATE_ARDUINO = True

COMMAND_DELAY_TIME = 1  # send a command to servos every n seconds


def main():
  servos = arduino.OpenArduino(sn=SN)
  format_string = '<lff'
  format_byte_size = arduino.SizeOf(format_string)
  azimuth=90

  while True:

    if not servos and not SIMULATE_ARDUINO:
      servos = arduino.OpenArduino(sn=SN)
      if VERBOSE:
        print('Reopening connection')

    if servos or SIMULATE_ARDUINO:
      if azimuth == 90:
        azimuth = 85
      else:
        azimuth = 90
      values = (0, azimuth, 0)

      arduino.StuffObject(servos, values, format_string, format_byte_size)
      if not SIMULATE_ARDUINO:
        servos.send(format_byte_size)


    time.sleep(COMMAND_DELAY_TIME)


if __name__ == "__main__":
  main()
error-handling arduino pyserial
1个回答
0
投票

我以杀死使用过长时间的函数调用的方法作为开端,并提出了使用StopItmultiprocessing的潜在解决方案。但是这些失败了,因为似乎实际发生的是pySerialTransfer产生了一个单独的线程来处理串行通信,然后将控制权返回给调用函数,但保持该单独的线程处于活动状态,而那个单独的线程被卡在其中无限错误循环。因此,我无法通过终止长时间运行的函数调用的解决方案来检测条件。并且如注释线程中所述,也没有任何异常传递给调用者,因此try-except子句也失败。

但是,我可以检测到的一件事是记录到stderr错误,因此,如果我可以重定向该错误并在那里检测到新错误,那将使我走上正确的道路。输入this guidance,这会将我引向该解决方案:

#!/usr/bin/python3

import sys
import time
import io

import arduino
import messageboard
import contextlib

VERBOSE = arduino.VERBOSE
SN = '75835343130351802272'  # arduino uno serial

SIMULATE_ARDUINO = arduino.SIMULATE_ARDUINO
if '-s' in sys.argv:
  SIMULATE_ARDUINO = True

COMMAND_DELAY_TIME = 1  # send a command to servos every n seconds


def main():
  servos = arduino.OpenArduino(sn=SN)
  format_string = '<lff'
  format_byte_size = arduino.SizeOf(format_string)
  azimuth=90

  while True:

    if not servos and not SIMULATE_ARDUINO:
      servos = arduino.OpenArduino(sn=SN)
      if VERBOSE:
        print('Reopening connection')

    if servos or SIMULATE_ARDUINO:
      if azimuth == 90:
        azimuth = 85
      else:
        azimuth = 90
      values = (0, azimuth, 0)

      # Detects any exceptions that print to stderr but are not raised to caller
      with io.StringIO() as buf, contextlib.redirect_stderr(buf):
        arduino.StuffObject(servos, values, format_string, format_byte_size)
        if not SIMULATE_ARDUINO:
          servos.send(format_byte_size)

        # if there's an exception, probably the connection failed; clear the connection
        # so that it can be reopened at top of loop
        if buf.getvalue():
          servos = None

    time.sleep(COMMAND_DELAY_TIME)


if __name__ == "__main__":
  main()

[当我在测试过程中手动将USB电缆从arduino拔出然后再插回2倍时,这将导致以下stdio输出。

$ python3 arduino_servo_test.py 
SENT (12 byte struct): (0, 85, 0)
SENT (12 byte struct): (0, 90, 0)
SENT (12 byte struct): (0, 85, 0)
SENT (12 byte struct): (0, 90, 0)
SENT (12 byte struct): (0, 85, 0)
SENT (12 byte struct): (0, 90, 0)
SENT (12 byte struct): (0, 85, 0)
SENT (12 byte struct): (0, 90, 0)
SENT (12 byte struct): (0, 85, 0)
SENT (12 byte struct): (0, 90, 0)
SENT (12 byte struct): (0, 85, 0)
SENT (12 byte struct): (0, 90, 0)
SENT (12 byte struct): (0, 85, 0)
SENT (12 byte struct): (0, 90, 0)
Reopening connection
Reopening connection
Reopening connection
Reopening connection
SENT (12 byte struct): (0, 85, 0)
SENT (12 byte struct): (0, 90, 0)
SENT (12 byte struct): (0, 85, 0)
SENT (12 byte struct): (0, 90, 0)
SENT (12 byte struct): (0, 85, 0)
SENT (12 byte struct): (0, 90, 0)
SENT (12 byte struct): (0, 85, 0)
SENT (12 byte struct): (0, 90, 0)
SENT (12 byte struct): (0, 85, 0)
SENT (12 byte struct): (0, 90, 0)
SENT (12 byte struct): (0, 85, 0)
SENT (12 byte struct): (0, 90, 0)
Reopening connection
Reopening connection
Reopening connection
Reopening connection
Reopening connection
Reopening connection
Reopening connection
SENT (12 byte struct): (0, 85, 0)
SENT (12 byte struct): (0, 90, 0)
SENT (12 byte struct): (0, 85, 0)
SENT (12 byte struct): (0, 90, 0)
SENT (12 byte struct): (0, 85, 0)
SENT (12 byte struct): (0, 90, 0)
SENT (12 byte struct): (0, 85, 0)
SENT (12 byte struct): (0, 90, 0)
SENT (12 byte struct): (0, 85, 0)
SENT (12 byte struct): (0, 90, 0)

问题已解决-也许不是最优雅的解决方案,但似乎可行。

© www.soinside.com 2019 - 2024. All rights reserved.