Caroline
Caroline

Reputation: 41

Serial.read in python is losing data

I wrote the function below to read data from a serial port. When I call it to read 33 bytes, it stops reading halfway. The bytearray msg returned contains only the first few bytes, the rest is lost. And the last byte read is different from '\n', so I don't know what could be interrupting the reading. But if I set a delay of microseconds between one byte and another on the device that is sending the bytes, the reading occurs normally. How can I solve this in my code, without adding this delay?

      comm = serial.Serial(slaveName, baudrate=115200, timeout=10000)
      def readLen(length):
            msg = comm.read(length)
            return bytearray(msg)
      data = readLen(33)

Edit: When I tried reading one byte at a time using a for loop the problem kept happening in exactly the same way.

Upvotes: 1

Views: 39

Answers (1)

Slava Koshman
Slava Koshman

Reputation: 1

One possible solution is to read one byte at a time. And to validate and not lose data, come up with a data sending packet.

Example: $01101001;

Where $ is the first byte of the package, and ; the last byte.

One of the things I noticed was that you need to clean the receive and send buffers, so the sampling speed increases. But I did not check whether the packets are lost at this moment.

Code example:

import serial

buffer = b""
is_reading = False

with serial.Serial("/dev/ttyACM0", 115200) as ser:
    if ser.in_waiting:
        ser.reset_input_buffer()
    while True:
        if ser.in_waiting:
            byte = ser.read()
            if byte == b"$":
                is_reading = True
            elif byte != b";" and is_reading:
                buffer+= byte
            else:
                if is_reading:
                    is_reading = False
                    data = buffer.decode("utf-8")
                    buffer = b""
                    ser.reset_input_buffer()
                    ser.reset_output_buffer()

Upvotes: 0

Related Questions