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

标签 python pyserial

我在从通过 USB 连接的 Arduino 读取字符串的 Python 代码块时遇到问题。我知道串行不知道字符串是什么或关心。我正在使用serial.readline,从文档来看,它听起来像是完美的匹配,但我的字符串并不总是完整的。奇怪的问题是,字符串并不总是有字符串的前面,但它总是有字符串的结尾。我真的对此迷失了方向,我确信这只是我对读取串行数据的细微差别或 Python 如何处理它缺乏理解。

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

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 代码的问题。

最佳答案

在(串行)通信中,您应该始终期望收到部分答案。

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

关于Python serial.readline 没有接收到我的整行内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41418119/

相关文章:

Python 认为一个 3000 行的文本文件是一行长?

Python serial.readline() 不阻塞

python - pyserial 2.7 文档错误,python 3.4 TypeError : an integer is required

python - 如何在 Python 中调用 sudo 密码请求

python - 使用列表理解创建嵌套列表

python - 模型没有出现在 django 管理中

python - 用于获取字符串一部分的正则表达式

python - 在每个 pandas 数据框行中查找前 n 个最高值列的名称

python - Pyserial - RS232 9600,8,N,1 发送和接收数据

python:从 serial.read() 解析字符串