1

I am trying to implement a system where outputs from an Arduino can be passed on to and printed in Python.

I have the following Arduino code snippet below:

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

My Python code snippet is as follow:

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!")

In the above example, I am trying to send inputs to Arduino via ASCIIdata, and when it matches the if-statement in Arduino, commands in the if-statement will be executed. I have purposely not do a print in Arduino and attempt to read something from Python by doing:

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

I observed that if I do not put raise in the try statement, the except statement will not be executed, but the program moves on after the specific timeout. Hence, I put raise in the try statement. May I ask if this is the correct approach to raising an exception?

I read that I should be doing except Exception as e instead of doing except because I would be catching all kinds of exception while the program is running. May I ask if this thought process is correct?

3
  • "Fail to send" should be a try-except around arduino.write(strin.encode()), no? Commented Nov 7, 2017 at 12:55
  • Hi grovina. Thank you for your reply. :) I am sorry, but may I ask what do you mean? I am trying to print "Fail to send" in Python, to indicate that Arduino did not send anything out even though the instructions in Arduino has been executed. Thank you! :) Commented Nov 7, 2017 at 13:08
  • 1
    @grovina as far as I understood in fact the OP is not trying to detect a failure in the serial driver preventing the message to exit, but to detect a issue in the code; the "Fail to send" should be read as "Device does not communicate with the PC" Commented Nov 7, 2017 at 13:08

2 Answers 2

1

First of all, I'm not very much into Python, so I'm not really sure, but having experience in other languages I think that this answer is correct.

What you did is... wrong. You don't want to raise an exception every time.

Looking at the documentation of the readline function,

readlines() depends on having a timeout and interprets that as EOF (end of file). It raises an exception if the port is not opened correctly.

This means that a timeout does not raise exceptions. You can test if the buffer is empty:

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

Even if you may just skip the exception:

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

If you prefer another behavior, write your own function (for instance this answer has something which looks like a reading function; you'll just have to add the exception raising.

As for the type of exception, usually it is best to use just one type of exception, in order to avoid catching everything. For instance:

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
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you gre_gor and frarugi87 for your answers! ^^ I am sorry for my late reply as I had exams (which ended yesterday) so I am back to doing this project! :) Thank you so much for your help once again~~ :D I tried implementing with the print buff if not buff: raise method and it worked! :) Thank you! :) I think I will write my own class in the future, but for now I think I will stick to the "if not buff: raise" method.
Just wondering, will writing my own class be better than writing the "if not buff: raise" method? Thank you once again! ^^
@galaxy_twirl in my opinion, it is not worth. But I'd avoid the raise and go directly with the if not buff printf (why do you have to raise an exception?), unless you strictly require an exception.
I see. I think I have a misconception that if I use "try", I must do an "except" to handle things that the try-statement has failed to do. I think I will re-think my thought process. Thank you so much for your enlightenment. :)
1

To answer your first question, this is the correct way to catch exceptions. The caveat is that you need to know what exceptions the code inside the try block raises. In your case arduino.readline() will only raise an exception on a serial port issue. In other words you don't need to call raise yourself because that means it will always look like a failure.

Using except Exception as e allows you to handle specific exceptions that code in the try block might raise. This way you can respond in different ways.

For example you might have different response for different errors:

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

1 Comment

Thank you zerox1212 for your answer! ^^ I am sorry for my late reply as I had exams (which ended yesterday) so I am back to doing this project! :) Thank you so much for your help once again~~ :D

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.