I have an Arduino programmed to print a line containing eight values separated by commas every 10 milliseconds. Every line is terminated by a new line character. But when I try to read this data into Python using pySerial, it doesn't read the entire line. PySerial starts to read lines from the middle, sometimes giving weird values. But when I open the Arduino serial monitor, all the data is displayed correctly. How to I fix this?
closed as off-topic by Bence Kaulics, Daniel Grillo, brhans, Peter Smith, uint128_t Jun 13 '16 at 13:55
- This question does not appear to be about electronics design within the scope defined in the help center.
PySerial (and serial libraries in general) have no idea of the concept of a "line".
port.read(), you get what is in the serial buffer right then, so if you opened the serial port when the arduino was partway through sending a serial message, you're going to get just the latter half of that message. If you call
read() when the arduino has only sent half of the message, you're going to get the first half of the message.
The solution here is to read until you see the new-line character. Since you know that each message is ASCII text followed by a newline, you can use the position of newline characters to divide the input stream.
Conveniently, pySerial has calls for this already:
There are things to be aware of when using
readline(), though. From the PySerial documentation (which you should be reading):
Be carefully 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.
Serial is a stream interface, not a message interface. It has no concept of any unit of data larger then a byte. As such, it is implicit on the user (in this case, you) to implement something that provides message delimiters. With ASCII, this is fairly easy since you aren't using every possible value that each byte can hold, but for systems that use binary messaging protocols, it can be quite involved.
Further note: You really should have asked this question on https://arduino.stackexchange.com/