Reputation: 23
I'm trying to redirect binary data from one serial port to a database using pySerial.
The problem is that pySerial allows only reading single characters with serial.read()
and a whole line until an EOL character with serial.readline
. However, the used protocoll (RTCMv3) is binary and messages vary in length, which means readline won't work and read will only give me a sequence of bytes. What I would like to achieve is to distinguish between individual messages.
I've tried the same with socat. Socat is somehow able to find out the length of the single messages without knowledge about the protocoll structure itself:
socat -u -x /dev/ttyUSB2,raw -
> 2018/03/15 21:04:24.394224 length=171 from=9 to=179 d3 00 a5 3e c0 00 72
7d b1 40 a0 3c 26 c5 91 fc fc 9f d3 30 f0 07 7f 82 27 fd 82 [...] 9f f0 f8
Is there a similar way of implementing this with Python/pySerial?
Upvotes: 0
Views: 5263
Reputation: 343
I think you're looking for either the serial.readline()
or
serial.read_until()
methods:
https://pyserial.readthedocs.io/en/latest/pyserial_api.html#serial.Serial.readline
https://pyserial.readthedocs.io/en/latest/pyserial_api.html#serial.Serial.read_until
Both allow variable length messages as long as the same ending delimiter is found. Both work well but the newline character can occasionally be a normal part of the binary data being transmitted which causes difficulty for serial.readline()
. If you can detect the message frame's ending character, or delimiter then serial.read_until()
would be useful.
Using an encoding method like COBS that guarantees removal of a delimiter character (the zero byte, b'\x00'
) will help find the end of each message. If you cannot change the sending protocol, you may need to search for the delimiter and packet structure it's using.
Upvotes: 1