pySerial 中的 readline() 有时会捕获从 Arduino 串行端口流式传输的不完整值

readline() in pySerial sometimes captures incomplete values being streamed from Arduino serial port

Arduino 每隔一秒打印(串行)“当前时间(以毫秒为单位)和 Hello world”。在串行监视器上,输出看起来不错。

但在pySerial中,有时会在字符串中间换行。

313113   Hel
lo world
314114   Hello world
315114   Hello world

我的 python 代码如下:

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)

我做错了什么?

我的配置:

Python 3.7
pySerial 3.4
Board Arduino Mega

这个问题肯定是由非常快的读取引起的,当 Arduino 的串行输出尚未完成发送完整数据时读取数据。

现在通过此修复,pySerial 将能够接收到完整的数据,不会遗漏任何数据。主要的好处是它可以用于任何类型的数据长度并且休眠时间非常短。

我已经用下面的代码解决了这个问题。

# 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)