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.
If this question can be reworded to fit the rules in the help center, please edit the question.

  • 1
    \$\begingroup\$ Fix it by asking the pySerial developers, obviously the hardware works, so it's not an electrical engineering problem. \$\endgroup\$ – pipe Jun 13 '16 at 5:08
  • 5
    \$\begingroup\$ I'm voting to close this question as off-topic because it is a pure python programming question. \$\endgroup\$ – Bence Kaulics Jun 13 '16 at 8:22

PySerial (and serial libraries in general) have no idea of the concept of a "line".

When you 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: port.readline().

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/

  • \$\begingroup\$ The question is hardly unique to Arduino, but turns up virtually anytime a programmer makes their first attempt at claiming automatically generated data from a serial interface (though in today's world, that mostly means embedded systems). If it belonged anywhere else, the main Stackoverflow site would be the best candidate. \$\endgroup\$ – Chris Stratton Jun 13 '16 at 7:59
  • \$\begingroup\$ If the user should have asked somewhere else, why did you just encourage his behaviour by answering his question, solving his problem, thus proving that disregarding the guidelines and posting random questions here is an effective way of getting an answer? \$\endgroup\$ – pipe Jun 13 '16 at 8:40
  • 2
    \$\begingroup\$ @pipe - Because questions can be migrated with their answers, and I assume a mod will move it? Also, there are lots of stackexchange sub-sites, and the OP not knowing about arduino.stackexchange.com is completely understandable? Basically, I don't assume it's malicious until I see a habit of asking on the wrong SE site. \$\endgroup\$ – Connor Wolf Jun 13 '16 at 18:31
  • \$\begingroup\$ @ConnorWolf Ok, fair enough. I just don't think it's helpful to this website in the long run, but that can be argued forever... \$\endgroup\$ – pipe Jun 14 '16 at 6:22

Not the answer you're looking for? Browse other questions tagged or ask your own question.