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

Ash*_*tha 5 python arduino pyserial python-3.x

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

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

313113   Hel
lo world
314114   Hello world
315114   Hello world
Run Code Online (Sandbox Code Playgroud)

我的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)
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

我的配置:

Python 3.7
pySerial 3.4
板 Arduino Mega

Ash*_*tha 4

该问题似乎肯定是由非常快速的读取引起的,当 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)
Run Code Online (Sandbox Code Playgroud)