我有一个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()
我以杀死使用过长时间的函数调用的方法作为开端,并提出了使用StopIt和multiprocessing的潜在解决方案。但是这些失败了,因为似乎实际发生的是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)
问题已解决-也许不是最优雅的解决方案,但似乎可行。