It's worth mentioning up-front that while I have a background in CS, the number of Python scripts I've written in could likely be counted on the number of toes on a sloth's paw. That said, I started playing with PySerial to read from a USB barcode scanner. One problem I'm having is the timeout. If I set it too low, I miss scans. If I set it too high, the processor utilization is huge. Of course, this is mentioned in the documentation for PySerial:
Be careful when using readline(). Do specify a timeout when opening the serial port otherwise it could block forever if no newline character is received. Also note that readlines() only works with a timeout. 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.
Right. So, here's my simple code:
#!/usr/bin/env python
import serial
ser = serial.Serial('/dev/ttyACM0', rtscts=True, dsrdtr=True, timeout=0.05)
ser.baudrate = 115200
while True:
s = ser.readline()
if s:
print(s)
How do I appropriately read from a serial device without risking missed scans? Sure, the odds are incredibly low with that small of a timeout, but I'm wanting to use this for production purposes at my business, so let's assume that this is mission-critical. What's the proper way to approach this problem (again, assuming that my understanding of Python is nil)?
Thanks, everyone!
EDIT: Possible solution?
I came up with the following that doesn't use a timeout and simply reads a single character at a time until it reaches a newline. It seems like this is pretty light on processor utilization (which was the whole issue I was having). Of course, I need to account for other newline possibilities from different scanners, but is there any reason why this wouldn't work?
#!/usr/bin/env python
import serial
ser = serial.Serial('/dev/ttyACM0', rtscts=True, dsrdtr=True)
ser.baudrate = 115200
string = ""
while 1:
char = ser.read(1)
string += char
if char == '\r':
print(string)
string = ""