I have the following simple setup:
Serial Device -> PL2303 UART-to-USB -> Win10 machine -> myScript.py using PySerial 3.5
Serial device is connected to the PC via PL2303 UART-to-USB at COM10.
Serial device only sends data when its physical "Send" button is pressed, and it only sends one 20-char \r\n terminated line per press.
Simple code to read the serial device data:
import time
import os
import sys
import serial
ser = serial.Serial("COM10", 9600, timeout=0.5)
while(1):
if ser.in_waiting:
serial_data = str(ser.readline().decode('ascii')) #Read (receive) data
print("Received: " + serial_data) #Print data
time.sleep(0.01) #Slight delay just in case.
The code works fine. However, when the Serial device is unplugged (via USB-to-Serial plug pull) Python crashes with the following exception:
File "D:\Program Files\Python37\lib\serial\serialwin32.py", line 259, in in_waiting
raise SerialException("ClearCommError failed ({!r})".format(ctypes.WinError()))
serial.serialutil.SerialException: ClearCommError failed (OSError(22, 'The I/O operation has been aborted because of either a thread exit or an application request.', None, 995))
Now, warnings/exceptions whenever the serial device is physically unplugged are nothing new. PuTTy does that, and so do a number of other terminal emulators and logically so should do PySerial.
HOWEVER, I remember clear as day that at some point in development unplugging the serial device incited no reaction from PySerial. I could even "hot-swap" - unplug one serial device, plug in another and the script would still work and print the received data.
Is this "hot-swapping" possible or did I horribly misremember all of it?
You can use a try-except block to make it hot swappable. This works for me (using an Arduino as the serial device).
Currently the device must be plugged in when you start running the code. But you can put the initial serial.Serial call inside its own try-except block to avoid this. Or you could simply leave this line out completely, and it will still work fine.