我在从通过 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/