处理Arduino-Python通信中的异常

时间:2017-11-07 12:38:14

标签: python arduino

我正在尝试实现一个系统,其中Arduino的输出可以传递到Python并以Python打印。

我在下面有以下Arduino代码段:

void loop() {
  if (Serial.available()) {
    c = Serial.read();
    if (c == '1') {
      digitalWrite(pinLED1, HIGH);
      digitalWrite(pinLED2, LOW);
      //Serial.print("1 ON, 2 OFF\n");
    }

我的Python代码片段如下:

import serial
import time

arduino = serial.Serial('COM3', 9600, timeout=1)
msg = arduino.readline(arduino.inWaiting())  # read everything in the input buffer

time.sleep(3)

ASCIIdata = '121210'

for i in range(len(ASCIIdata)):

    if ASCIIdata[i] == '1':
        strin = '1'
        arduino.write(strin.encode())
        time.sleep(0.2)
        #print(ASCIIdata[i])
        try:
            print ("Message from arduino: ")
            print arduino.readline()
            raise
        except Exception as e:
            print ("Fail to send!")

在上面的例子中,我试图通过ASCIIdata向Arduino发送输入,当它与Arduino中的if语句匹配时,将执行if语句中的命令。我故意不在Arduino中打印并尝试通过以下方式从Python中读取内容:

try:
    print ("Message from arduino: ")
    print arduino.readline()
    raise
except:
    print ("Fail to send!")

我观察到如果我没有在try语句中放置raise,则不会执行except语句,但程序会在特定超时后继续运行。因此,我将raise放在try语句中。请问这是否是提出异常的正确方法?

我读到我应该做except Exception as e而不是做except,因为我会在程序运行时捕获各种异常。请问这个思维过程是否正确?

2 个答案:

答案 0 :(得分:1)

首先,我并不是很喜欢Python,所以我不太确定,但是我有其他语言的经验,我认为这个答案是正确的。

你做的是......错了。你不想每次raise例外。

查看the documentation of the readline function

  

readlines()取决于超时并将其解释为EOF   (文件结束)。如果端口未打开,则会引发异常   正确。

这意味着超时不会引发异常。您可以测试缓冲区是否为空:

try:
    print ("Message from arduino: ")
    buff = arduino.readline()
    print buff
    if not buff:
        raise
except:
    print ("Fail to send!")

即使您可能只是跳过例外:

print ("Message from arduino: ")
buff = arduino.readline()
print buff
if not buff:
    print ("Fail to send!")

如果您更喜欢其他行为,请编写自己的函数(例如,此答案具有看似阅读功能的内容;您只需添加异常提升。

对于异常的类型,通常最好只使用一种类型的异常,以避免捕获所有内容。例如:

class MyError(Exception):
    def __init__(self, value):
        self.value = value
    def __str__(self):
        return repr(self.value)

try:
    raise MyError(2*2)
except MyError as e:
    print 'My exception occurred, value:', e.value

答案 1 :(得分:1)

要回答您的第一个问题,这是捕获异常的正确方法。需要注意的是,您需要知道try块中的代码会引发什么异常。在您的情况下,arduino.readline()只会在串口问题上引发异常。换句话说,您不需要自己调用raise,因为这意味着它总是看起来像失败。

使用except Exception as e可以处理try块中的代码可能引发的特定异常。这样你就可以用不同的方式做出回应。

例如,您可能对不同的错误有不同的响应:

except OSError as err:
    print("OS error: {0}".format(err))
except ValueError:
    print("Could not convert data to an integer.")
except:
    print("Unexpected error:", sys.exc_info()[0])
    raise