Python 2.7 pySerial read() returns Python 解释器中的所有字符,但不是 Python 脚本中的所有字符。还需要稳健的方式来读取直到缓冲区为空

Python 2.7 pySerial read() returns all characters in Python interpreter but not Python script. Also need robust way to read until buffer is empty

我正在与一个微控制器通信,只要您打开它的串口,它就会自动初始化它的闪存。因此,在串行端口读取时,微控制器打印多达 10,000 字节的数据,显示地址及其初始值。您需要在整个打印过程中保持端口打开,以确保初始化完成。我从不执行任何写入,只是读取。

我将 pySerial 缓冲区从 4k 修改为 32k,因为我不希望读取之间有任何中断(后续读取将简单地重新启动初始化周期)。下面是我从微控制器串行端口读取的代码片段。当我 运行 来自解释器的这个片段时,我可以从 print 和 sizeof 中看出 temp 包含所有 9956 个字节。但是,当我 运行 py 文件时,我只得到 296 个字节。我在 read() 之后插入了 sleep() 方法,但这没有任何效果。我无法从微控制器判断初始化是否完成。

是否有可靠的方法读取串行缓冲区为空?微控制器图像是特定于应用程序的,所以我不能总是预测所需的 read() 大小或超时。

有什么我可以尝试的想法吗?我搜索了其他线程,但没有找到任何特定于此问题的内容。

# Create serial port instance
self.ser_port = serial.Serial()
self.ser_port.port = 0
self.ser_port.timeout = 0
.
.
.
self.ser_port.open()
time.sleep(1)
temp = self.ser_port.read(32768)
time.sleep(4)
self.ser_port.close()

0 的超时告诉 pySerial 立即 return 使用任何已经可用的数据。如果您希望 read() 等待更多数据进入,请使用非零超时。

第一个 sleep() 可能会导致您丢失一些在 open 之后但在 read 之前的数据,因为内部缓冲区可能没有缓冲区那么大您正在传递给 read()。但这高度依赖于应用程序——如果您正在与之通信的设备在 open() 之后需要一段时间才能响应,那么这可能不是问题。

第二个 sleep() 对您没有任何作用,因为 read() 在那个时候已经完成了。

请注意,超时值是最大总计 等待时间。 read() 将 return 当它已填满其缓冲区时,或者在它被调用后这么长时间,以先到者为准。

下面是一些示例代码,在以下情况下 return:

a) 10-12 秒无数据

b) 如果至少收到 100 个字节

,最后一个数据 returned 后 2-4 秒静默
self.ser_port = serial.Serial()
self.ser_port.port = 0
self.ser_port.timeout = 2
.
.
.

self.ser_port.open()
timeout_count = 0
received = []
data_count = 0
while 1:
    buffer = self.ser_port.read(32768)
    if buffer:
        received.append(buffer)
        data_count += len(buffer)
        timeout_count = 0
        continue
    if data_count > 100:
        # Break if we received at least 100 bytes of data,
        # and haven't received any data for at least 2 seconds
        break
    timeout_count += 1
    if timeout_count >= 5:
        # Break if we haven't received any data for at
        # least 10 seconds, even if we never received
        # any data
        break

    received = ''.join(received)  # If you need all the data

根据您的微控制器,您可以大大减少这些超时值,并且仍然有一个相当强大的解决方案来从微控制器检索所有启动数据。