Search code examples
python-3.xexceptionserial-portpyserial

Pyserial PermissionError after program crash


I have a problem similar to this article: pySerial PermissionError(13, 'Access denied', None, 5)

On my first run of the program it will open the port perfectly, but if the a user kills the program in task manager, or the program crashes, a subsequent run of the program produces the following error:

could not open port 'COM3': PermissionError(13, 'Access is denied.', None, 5)

Looking at my code here:

def connect(self):
                try:
                        self.ser = serial.Serial(port=self.ser_config.com_port,baudrate=self.ser_config.baud_rate, parity=self.ser_config.parity,xonxoff=self.ser_config.xonxoff, timeout=self.ser_config.timeout)
                        if self.ser.is_open:
                                print("Serial port " + self.ser_config.com_port + " opened!")
                                print("Serial Configuration: baud_rate=" + str(self.ser_config.baud_rate))
                                return True
                        else:
                                if self.ser:
                                        self.ser.close()
                                print("Could not open serial port.")
                                return False
                except serial.SerialException as se:
                        if self.ser:
                                self.ser.close()
                        print("Serial port " + self.ser_config.com_port + " not found or cannot be configured")
                        print(se)
                        return False

I'm assuming this is becuase when the first program ran, it took exclusive privelages on the port, but now the 2nd run can't access it. And I can't do a self.ser.close() because self.ser = None in the case of an error.

Does anyone know of a way to force close the port in this instance or another way to open it so that the user doesn't need to restart their computer or manually close the port upon a failure of the program?


Solution

  • If you write your serial connection as a class, you can use the del() method to close the connection when the object is destroyed upon closing the program.

    def __del__(self):
        """Close connection upon object destruction."""
        if self.connection.is_open:
            print('Destroying instance.')
            self.connection.close()
    

    That doesn't help too much if it's a program crash, per your question. The brute force option would be to wrap a bunch of your code in a try/except/else block and close the connection upon any error.

    Or discontinue developing on Windows machines. There is no way around this issue through python alone.