我正在尝试在我的电脑(Windows10)上使用Python从通过USB以115200波特率连接的另一台设备读取数据。我想一一到达字节,所以我使用
serial.read()
函数。
我想使用 time
检查程序性能,并且我发现正在读取的每个第 64 个值都会出现读取时间不一致的情况。该特定步骤所花费的时间比其他值高 50 到 100,使程序变慢,有时会导致数据丢失...
经过一番研究,我认为这是由于根据讨论
这里的
append
功能实现造成的,但这并没有解决我的问题。
我相信问题来自 read()
函数,但我不明白为什么会发生。
这是我的代码:
import serial
import time
counter_max = 24*100
test_mode = 0
PORT = 'COM12'
BAUDRATE = 115200
uart_port = serial.Serial()
uart_port.port = PORT
uart_port.baudrate = BAUDRATE
uart_port.timeout = None
uart_port.open()
counter = 0
if test_mode == 0:
# --- LIST VERSION -----------------------------------------------------------
elapsed_times = []
uart_datas = []
while counter < counter_max:
time_start = time.perf_counter_ns()
uart_data = uart_port.read()
uart_datas.append(uart_data)
time_stop = time.perf_counter_ns()
elapsed = time_stop - time_start
elapsed_times.append(elapsed)
counter += 1
elif test_mode == 1:
# --- PREALOCATTED LIST VERSION ----------------------------------------------
elapsed_times = [None] * (counter_max)
uart_datas = [None] * (counter_max)
while counter < counter_max:
time_start = time.perf_counter_ns()
uart_data = uart_port.read()
uart_datas[counter] = uart_data
time_stop = time.perf_counter_ns()
elapsed = time_stop - time_start
elapsed_times[counter] = elapsed
counter += 1
uart_port.close()
# print(elapsed_times)
任何帮助理解为什么会发生这种情况以及我如何避免它的帮助,将不胜感激!谢谢
正如您所说,您正在使用微控制器,因此第一步是检查数据速率是否确实符合您的预期。使用示波器,或者更好的是逻辑分析仪来确保没有 50-100 倍高的间隙,并确保您确实按照预期发送数据。
每次调用
read()
方法时,python都必须转到操作系统,操作系统转到任何软件缓冲区,并且可能有也可能没有硬件缓冲区。每个第 64 个字节都很有趣...可能有一个 64 字节缓冲区表示缓存未命中或其他类似情况。我怀疑只要您一次读取一个字节,您就会继续经历这种情况。
更好的解决方案是读取所有可用数据并按顺序解析它 - 如果这是您想要做的。
byte_counts = []
elapsed_times = []
uart_datas = []
while counter < counter_max:
time_start = time.perf_counter_ns()
uart_data = uart_port.read(uart_port.in_waiting)
uart_datas += uart_data
byte_counts.append(byte_counts)
time_stop = time.perf_counter_ns()
elapsed = time_stop - time_start
elapsed_times.append(elapsed)
counter += 1
# check here to see how many bytes you received between
# while loops by inspecting the `byte_counts` list; it is
# possible that you are reading 1 byte at a time when there
# are hundreds or even thousands available; also possible
# that there are none sometimes
Python 代码和操作系统代码之间的任何交互几乎肯定会涉及某种类型的缓冲区。缓冲区不喜欢一次读取一个,并且每 64 个字节的奇怪行为可能是物理或编译缓冲区对齐的指示。从理论上讲,这不应该是一个太大的问题,只是会大大减慢你的程序速度。
您对丢失数据的指示更有趣。如果您已确认您的微控制器确实正在发送所有数据,那么这可能表明存在缓冲区溢出。通过从操作系统读取所有可用数据,您应该足够频繁地清除数据,这不应该成为一个因素。
我怀疑这不会完全解决您的问题,但它将帮助您设计程序以提高性能并更好地与硬件配合使用。祝你好运,
j