Python的serial.readline没有收到我的整行

时间:2017-01-01 18:58:12

标签: python pyserial

我在使用通过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 IDE和串行监视器接口验证了我的Arduino正确播放。这绝对是我的Python代码的一个问题。

1 个答案:

答案 0 :(得分:2)

在(串行)通信中,您总是希望得到部分答案。

在这种情况下,通常的解决方案是将您从串行读取的任何内容添加到字符串/缓冲区,直到您可以使用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)

(来自this answer)。

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

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