4
votes

I have a Python script that writes data packets to an Arduino board through pySerial. Sometimes while writing the code to the board pySerial raises an input/output error with errno 5.

Some research says that this indicates an error while writing in the file representing the connection to the Arduino board.

The code that sends, sends only single byte packets:

try:
    # Check if it's already a single byte
    if isinstance(byte, str):
        if len(byte) == 1: # It is. Send it.
            self.serial.write(byte)
        else: # It's not
            raise PacketException
    # Check if it's an integer
    elif isinstance(byte, int):
        self.serial.write(chr(byte)) # It is; convert it to a byte and send it
    else: raise PacketException # I don't know what this is.
except Exception as ex:
    print("Exception is: " + ex.__getitem__() + " " + ex.__str__())

The error printed by this code is:

OS Error Input/Output Error Errno 5

Is there something wrong in my code while sending? Do I need to check if the serial connection is ready to send something or should there be a delay after the sending? Or could there be a problem with the hardware or the connection with the hardware?

Edit: I looked into the Linux implementation from pyserial and the implementation is only passing the error to my code. So no new real insights from there. Is there a good way to test what is happening in the program?

4

4 Answers

2
votes

Sorry to have bothered you but I'm very sure that the error is caused by the arduino resetting itself and therefore closing the connection to the computer.

1
votes

The only issue I can immediately see in your code is an indentation problem -- change your code as follows:

try:
    # Check if it's already a single byte
    if isinstance(byte, str):
        if len(byte) == 1: # It is. Send it.
            self.serial.write(byte)
        else: # It's not
            raise PacketException
    # else, check if it's an integer
    elif isinstance(byte, int): 
        self.serial.write(chr(byte)) # It is; convert it to a byte and send it 
    else: 
        raise PacketException # I don't know what this is.
except Exception as ex:
    print("Exception is: " + ex.__getitem__() + " " + ex.__str__())

I doubt your error comes from this, but try it this way and let us know! You were checking if byte is an int only in the case in which it's a str, so the elif always failed by definition. But I think if you real code indentation had been like this, you'd have gotten a SyntaxError, so I think you just erred in posting and your real problem remains hidden.

1
votes

If you are running this on Windows, you can't have the Arduino IDE open with a serial connection at the same time that you run your Python script. This will throw the same error.

0
votes

Let me try to offer a few comments that might be helpful to you and other folks with similar problems. First, try to run your Arduino sketch with the Serial Monitor a few times. You can find the Serial Monitor under Tools in the IDE menu. You can also type Ctrl-Shift-M to invoke the Serial Monitor.

The Serial Monitor displays what the Arduino sketch sends back to you. However, it also lets you type in data that gets sent to the Arduino sketch. In other words you test and debug both sides of the serial data flow, just using the Serial Monitor.

Look at what shows up. It will frequently be quite helpful assuming your sketch tries to send data back via Serial.print(). A few notes. Make absolutely sure that the baud rate set inside the Serial Monitor exactly matches the baud rate in your sketch (9600 is a good choice in almost all cases).

The second note is critical. Bringing up the Serial Monitor forces a reset on the Arduino board. Your sketch starts over (always). This is a good thing because it gives you a fresh run each time. Note that you can force a reset, just by setting the baud rate to 9600 (even if it is already 9600). This lets you run many tests inside the Serial Monitor without having to restart the Serial Monitor each time.