Reputation: 388
Every one second, Arduino prints (in serial) 'current time in milliseconds and Hello world'. On serial monitor, the output looks fine.
But in pySerial
, sometimes there is line break at the middle of string.
313113 Hel
lo world
314114 Hello world
315114 Hello world
My python code is as:
import serial
import time
ser = serial.Serial(port='COM4',
baudrate=115200,
timeout=0)
while True:
str = ser.readline() # read complete line
str = str.decode() # decode byte str into Unicode
str = str.rstrip()
if str != "":
print(str)
time.sleep(0.01)
What am I doing wrong?
My configuration:
Python 3.7
pySerial 3.4
Board Arduino Mega
Upvotes: 5
Views: 6650
Reputation: 388
The problem definitely seems to be caused by very fast reads where the data is read when the serial output from the Arduino hasn't finished sending full data.
Now with this fix, the pySerial
will be able to receive the complete data and no data is missed. The main benefit is that it can be used for any type of data length and the sleep time is quite low.
I have fixed this issue with code below.
# This code receives data from serial device and makes sure
# that full data is received.
# In this case, the serial data always terminates with \n.
# If data received during a single read is incomplete, it re-reads
# and appends the data till the complete data is achieved.
import serial
import time
ser = serial.Serial(port='COM4',
baudrate=115200,
timeout=0)
print("connected to: " + ser.portstr)
while True: # runs this loop forever
time.sleep(.001) # delay of 1ms
val = ser.readline() # read complete line from serial output
while not '\\n'in str(val): # check if full data is received.
# This loop is entered only if serial read value doesn't contain \n
# which indicates end of a sentence.
# str(val) - val is byte where string operation to check `\\n`
# can't be performed
time.sleep(.001) # delay of 1ms
temp = ser.readline() # check for serial output.
if not not temp.decode(): # if temp is not empty.
val = (val.decode()+temp.decode()).encode()
# requrired to decode, sum, then encode because
# long values might require multiple passes
val = val.decode() # decoding from bytes
val = val.strip() # stripping leading and trailing spaces.
print(val)
Upvotes: 4