Python';s serial.readline未接收我的整行

Python';s serial.readline未接收我的整行,python,pyserial,Python,Pyserial,我在从通过USB连接的Arduino读取字符串中的Python代码块时遇到问题。我知道那个连续剧不知道什么是字符串,也不在乎。我使用的是serial.readline,这在文档中听起来像是完美的匹配,但我的字符串并不总是完整的。奇怪的问题是,字符串并不总是有字符串的前面,但它总是有字符串的结尾。我真的很迷茫,我确信这是因为我不了解读取串行数据的细微差别,或者Python如何处理它 在下面的代码中,我循环遍历串行接口,直到找到要查找的接口。我刷新输入并让它休眠几秒钟,以确保它有时间重新读取 ard

我在从通过USB连接的Arduino读取字符串中的Python代码块时遇到问题。我知道那个连续剧不知道什么是字符串,也不在乎。我使用的是serial.readline,这在文档中听起来像是完美的匹配,但我的字符串并不总是完整的。奇怪的问题是,字符串并不总是有字符串的前面,但它总是有字符串的结尾。我真的很迷茫,我确信这是因为我不了解读取串行数据的细微差别,或者Python如何处理它

在下面的代码中,我循环遍历串行接口,直到找到要查找的接口。我刷新输入并让它休眠几秒钟,以确保它有时间重新读取

arduinoTemp = serial.Serial(iface, 9600, timeout=1)
arduinoTemp.flushInput()
arduinoTemp.flushOutput()
arduinoTemp.write("status\r\n".encode())
time.sleep(2)
read = arduinoTemp.readline().strip()
if read != "":
    #check the string to make sure it's what I'm expecting.
我用JSON发送字符串

我期待着与此相一致的东西:

 {"id": "env monitor","distance": {"forward": {"num":"0","unit": "inches"}},"humidity": {"num":"0.00","unit": "%"},"temp": {"num":"0.00","unit": "fahrenheit"},"heatIndex": {"num":"0.00","unit": "fahrenheit"}}
我可能会得到这样的回报:

 ": t": "%"},"temp": {"num":"69.80","unit": "fahrenheit"},"heatIndex": {"num":"68.13","unit": "fahrenheit"}}
或者这个:

atIndex": {"num":"0.00","unit": "fahrenheit"}}
起初,我认为可能是字符串的长度导致了一些问题,但是截断并不总是一致的,因为它有字符串的结尾,所以它理所当然地应该在这之前得到所有东西

我已经通过直接与Arduino接口以及Arduino IDE和串行监视器验证了我的Arduino是否正确广播。这肯定是我的Python代码的一个问题。

在(串行)通信中,您应该总是希望收到部分答案

在这种情况下,通常的解决方案是将从序列中读取的内容添加到字符串/缓冲区,直到可以使用
json.loads
成功解析它

import serial
import json
import time

ser = serial.Serial('/dev/ttyACM0', 9600)

buffer = ''
while True:
    buffer += ser.read()
    try:
        data = json.loads(buffer)
        print(data)
        buffer = ''
    except json.JSONDecodeError:
        time.sleep(1)
(来自)

请注意,如果刷新,将丢失数据


还请注意,这是一个稍微简化的解决方案。理想情况下,应该将缓冲区重置为成功解析后剩余的内容。但据我所知,
json
模块不提供这种功能。

如果您总是在最后一行,这会告诉我readline()知道何时停止。因此,我会尝试移除或大大减少睡眠(2),让readline()尽快开始工作。这可能是我无法理解pyserial的细微差别的地方。我刷新了输入,然后想等一秒钟,等待状态ping返回响应。我把它改为睡眠前一秒和睡眠后一秒,我只是有点不明白为什么我要削减强的开始。有一段时间以来,我使用pyserial,但我建议删除任何睡眠,如果需要的话,只给Serial()一个更长的超时值。此外,除非您确定需要,否则我不会定期刷新()输入。希望我能提供更多。我有一些类似的东西,只是我在读一行。我想我必须放弃这一点,转而使用你给我的缓冲区解决方案,但真正让我反感的是我的代码,虽然它没有给我整个字符串,但它总是给我字符串的结尾,而不是开始。@JohnSly两个可能的原因是刷新缓冲区或缓冲区溢出。硬件缓冲区的大小无法更改,但您应该能够在串行驱动程序中设置内存缓冲区的大小。如何做到这一点是操作系统特有的。