【问题标题】:pyserial issues with high baudrate FTDI高波特率 FTDI 的 pyserial 问题
【发布时间】:2020-11-11 16:22:27
【问题描述】:

我有以下设置:

  • FPGA 以 3Mbps 的波特率在 UART 上发送数据。传输的数据是一个 1024 字节的块,以 20 毫秒到 200 毫秒的可变周期发送。 (所以即使在最坏的情况下,数据率也远非 3Msps)

  • FTDI 232RG

  • 在我的计算机(Windows)上运行的一段python,基本上是:用pyserial,3Msps打开一个COM端口,轮询in_waiting直到它达到一个数据包的大小(1024字节),格式化接收到的数据包并打印它在屏幕上

该脚本适用于低重复频率,但我面临更高重复次数(通常为 20 毫秒)的问题。当以 20 毫秒为周期时,我最终会在 in_waiting 之前的某个地方出现缓冲区溢出。我检查了我的 python 循环的时间,大约需要 4 毫秒。所以看起来上游(在 FTDI 或 Windows 中)有一些东西在一个数据包之后的 4 毫秒内向 pyserial 缓冲区提供多个数据包。

我尝试更改驱动程序中的 FTDI 延迟(从默认的 16 毫秒降低到几毫秒),但似乎没有帮助。

我目前对正在发生的事情一无所知。您对如何更好地了解正在发生的事情有什么建议吗?

感谢您的帮助!

【问题讨论】:

  • 你是如何查看时间的? 4毫秒是平均值/最小值/最大值吗?我们在谈论哪个操作系统?
  • nvm 操作系统问题。是否过度阅读了 Windows 部分。
  • 嗨,Christian,我将循环时间计算为进入循环的那一刻(in_waiting 至少是数据包大小)与以下 in_waiting 评估的时间之间的时间差。由于数据包长度恒定,数据包恒定,我的机器负载不重,最大4ms,平均约3.8ms,最小约3.8ms。
  • 啊等等。您如何定义“缓冲区溢出”。数据会丢失吗?还是只是“一次太多数据”?因为这是预期的,因为 FTDI 集群接收数据,直到接收到足够的 USB 帧或直到触发超时。它类似于 TCP 的 Nagle 算法。
  • 一些数据丢失了,因为我传输的数据是一个 16 位数字的列表,我看到在某个时刻,LSB 和 MSB 被“交换”,表明丢失了奇数个字节(偶数字节的丢失将丢失整个 16 位,我可能无法理解)。我知道我期望的值(在给定范围内),所以当我看到“字节序变化”时,我会看到数据丢失,即使发生的是字节序变化,而是丢失了一大块数据。你明白我的意思吗?

标签: buffer pyserial ftdi


【解决方案1】:

您可以在 TX 和 RX 之间创建一个“循环”并运行以下代码(使用 FT2232H 进行测试,因此您很可能需要更改标识符字符串):

import time
import serial
import serial.tools.list_ports


print([(x[0],x[2]) for x in serial.tools.list_ports.comports()])
port    = [x[0] for x in serial.tools.list_ports.comports() if "FT4Q1LJFB" in x[2]][0]
ser     = serial.Serial(port,12000000)

while True:
    t0      = time.time()
    counter = 0
    for i in range(1000):
        ser.write([1]*3000)
        recv    = ser.read(ser.inWaiting())
        delta_t = time.time() - t0
        counter += len(recv)
        
    print(counter / delta_t)
    

对我来说显示以下输出

[('COM7', 'USB VID:PID=0403:6010 SER=FT4Q1LJFA'), ('COM8', 'USB VID:PID=0403:6010 SER=FT4Q1LJFB')]
0.0
0.0
0.0
0.0
96787.81184093593
1201991.0268273412
1201197.0857713912
1201166.9350959768
1201445.4072856384

您会注意到它的开头是 0.0。这是因为我在启动程序后连接了 RX 和 TX,导致接收到的字节数增加。这是“默认”模式,意味着 8 位 + 1 个起始位 + 1 个停止位 = 每个字 10 位,这解释了为什么“仅”每秒传输 1.2 MB。

【讨论】:

  • 感谢 Christian 提供的代码。在我的情况下确实有用甚至更简单,因为我没有 TX(FPGA 在周期事件上无条件发送)。当我手头有设置(Covid 家庭办公室)时,我将测试此代码。据我记得,在某些情况下,我会在 4ms(最多)循环内收到 >3000 个字节,因此它会报告 >750kB/s(超过 3Mbps)。我会尽快检查。一个想法可能是只读取而不进行处理以加速循环,并可能更好地看到“突发”事件
  • 我有机会测试你的想法,但基本上结果和你得到的一样。我基本上在我期望的值周围得到了一些抖动(这是可以预料的,因为我的 UART 流是周期性的),并且我在系统“出错”时得到的结果与我在系统时看到的抖动没有什么不同作品。我不太了解哪里出了问题。
猜你喜欢
  • 2019-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多