I have the same problem and implemented my own readline () function, which I copied and modified from the serialutil.py file found in the pyserial package.
A serial connection is part of the class to which this function belongs and is stored in the "self.ser" attribute
def _readline(self): eol = b'\r' leneol = len(eol) line = bytearray() while True: c = self.ser.read(1) if c: line += c if line[-leneol:] == eol: break else: break return bytes(line)
This is a safer, more convenient and faster option than waiting for a timeout.
EDIT: I came across this when trying to get io.TextIOWrapper to work (thanks to zmo ), so instead of using the custom readline function as above, you can use:
self.ser = serial.Serial(port=self.port, baudrate=9600, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, timeout=1) self.ser_io = io.TextIOWrapper(io.BufferedRWPair(self.ser, self.ser, 1), newline = '\r', line_buffering = True) self.ser_io.write("ID\r") self_id = self.ser_io.readline()
Be sure to pass argument 1 to BufferedRWPair , otherwise it will not pass data to TextIOWrapper after each byte, causing a reconnection to the timeout.
When setting line_buffering to True you no longer need to call the flush function after each record (if the record ends with a newline).
EDIT: The TextIOWrapper method works in practice for small command lines, but its behavior is undefined and can lead to errors when transmitting more than two bytes. The safest thing to do is implement your own version of readline .
source share