pyserial - 如何读取来自串口设备的最后一行数据
我有一个Arduino设备,它连接着我的电脑,并且在不断循环,每100毫秒就会通过串口发送一个数值回电脑。
我想写一个Python脚本,让它每隔几秒钟读取一次串口的数据,这样它就只需要看到Arduino最后发送的内容。
请问在Pyserial中怎么实现这个功能呢?
这是我尝试过的代码,但它不管用,因为它是顺序读取每一行数据。
import serial
import time
ser = serial.Serial('com4',9600,timeout=1)
while 1:
time.sleep(10)
print ser.readline() #How do I get the most recent line sent from the device?
10 个回答
你可以使用 ser.flushInput()
来清空当前缓冲区里的所有串口数据。
在清除掉旧数据后,你可以使用 ser.readline()
来获取串口设备最新的数据。
我觉得这个方法比这里其他人提的解决方案简单一些。对我有效,希望也适合你。
在编程中,有时候我们会遇到一些问题,特别是在使用某些工具或库的时候。比如,有人可能在使用某个库时,发现它的某些功能没有按照预期工作。这种情况可能会让人感到困惑,因为我们可能不知道问题出在哪里。
解决这类问题的一个好方法是查看文档。文档通常会详细说明如何正确使用这个库,里面可能会有示例代码和常见问题的解答。如果文档没有解决你的疑问,可以考虑在网上搜索一下,看看其他人是否遇到过类似的问题。
另外,参与社区讨论也是一个不错的选择。你可以在像StackOverflow这样的论坛上提问,描述你的问题和你尝试过的解决方法。这样,其他有经验的人就能帮助你找到问题的根源。
总之,遇到问题时不要慌张,先查文档、搜索资料,或者向社区求助,通常都能找到解决办法。
from serial import *
from threading import Thread
last_received = ''
def receiving(ser):
global last_received
buffer = ''
while True:
# last_received = ser.readline()
buffer += ser.read(ser.inWaiting())
if '\n' in buffer:
last_received, buffer = buffer.split('\n')[-2:]
if __name__ == '__main__':
ser = Serial(
port=None,
baudrate=9600,
bytesize=EIGHTBITS,
parity=PARITY_NONE,
stopbits=STOPBITS_ONE,
timeout=0.1,
xonxoff=0,
rtscts=0,
interCharTimeout=None
)
Thread(target=receiving, args=(ser,)).start()
也许我误解了你的问题,但因为这是一个串行连接,你需要顺序读取从Arduino发送过来的所有数据——这些数据会在Arduino里被缓存,直到你去读取它。
如果你想要一个状态显示,能够显示最新发送的内容——可以使用一个线程,把你提到的代码放进去(去掉睡眠的部分),并把最后读取到的完整行保存为来自Arduino的最新行。
更新:mtasic
的示例代码挺不错的,但如果在调用inWaiting()
时Arduino发送了一部分数据,你会得到一行不完整的数据。你应该把最后一行完整的数据放入last_received
,而把不完整的部分保存在buffer
里,以便下次循环时可以继续拼接。可以这样做:
def receiving(ser):
global last_received
buffer_string = ''
while True:
buffer_string = buffer_string + ser.read(ser.inWaiting())
if '\n' in buffer_string:
lines = buffer_string.split('\n') # Guaranteed to have at least 2 entries
last_received = lines[-2]
#If the Arduino sends lots of empty lines, you'll lose the
#last filled line, so you could make the above statement conditional
#like so: if lines[-2]: last_received = lines[-2]
buffer_string = lines[-1]
关于使用readline()
:这是Pyserial文档中的一些说明(稍作编辑以便更清晰,并提到readlines()
):
使用“readline”时要小心。打开串口时一定要指定超时时间,否则如果没有接收到换行符,它可能会一直阻塞下去。此外,请注意“readlines()”只有在设置了超时时间的情况下才能工作。它依赖于超时,并将其视为文件结束(EOF)。
我觉得这些说法很合理!