6

我正在以 921600 的波特率通过串行从微控制器读取数据。我正在读取大量 ASCII csv 数据,并且由于它来得如此之快,因此缓冲区已被填满,并且所有其余数据在之前都丢失了我可以阅读它。我知道我可以手动编辑 serialwin32 的 pyserial 源代码以增加缓冲区大小,但我想知道是否有另一种解决方法?

我只能估计我将收到的数据量,但它大约是 200kB 的数据量。

4

5 回答 5

5

在将命令发送到 uC 以发送数据之前,您是否考虑过在单独的线程中从串行接口读取?

这将消除写入命令和开始读取之后的一些延迟。还有其他 SO 用户使用这种方法取得了成功,当然他们没有缓冲区溢出。

如果不清楚,请告诉我,我可以拼凑一些东西来展示这一点。

编辑

再想一想,如果您尝试从缓冲区读取并将其写入文件系统,即使独立线程也可能无法拯救您。为了尽量减少处理时间,您可以考虑一次读取 100 个字节,serial.Read(size=100)并将该数据推送到队列中,以便在传输完成后处理所有数据

伪代码示例

def thread_main_loop(myserialobj, data_queue):
    data_queue.put_no_wait(myserialobj.Read(size=100))

def process_queue_when_done(data_queue):
    while(1):
        if len(data_queue) > 0:
            poped_data = data_queue.get_no_wait()
            # Process the data as needed
        else:
            break;
于 2012-04-12T16:59:06.720 回答
4

有一个“接收缓冲区”滑块,可从设备管理器中 com 端口的属性页面访问。它可以通过“端口设置”​​选项卡上的“高级”按钮找到。

com 端口的高级设置

更多信息:

http://support.microsoft.com/kb/131016在标题接收缓冲区下

http://tldp.org/HOWTO/Serial-HOWTO-4.html在标题下的中断

尝试将其降低一两个档次。

于 2012-04-12T19:56:30.473 回答
1

您不需要手动更改 pyserial 代码。

如果你在 Windows 平台上运行你的代码,你只需要在你的代码中添加一行

ser.set_buffer_size(rx_size = 12800, tx_size = 12800)

其中 12800 是我选择的任意数字。您可以将接收(rx)和传输(tx)缓冲区设为 2147483647a


也可以看看:

https://docs.python.org/3/library/ctypes.html

https://msdn.microsoft.com/en-us/library/system.io.ports.serialport.readbuffersize(v=vs.110).aspx

您也许可以从 DLL 设置串行端口 // 设置串行

 mySerialPort.BaudRate = 9600;
 mySerialPort.PortName = comPort;
 mySerialPort.Parity = Parity.None;
 mySerialPort.StopBits = StopBits.One;
 mySerialPort.DataBits = 8;
 mySerialPort.Handshake = Handshake.None;
 mySerialPort.RtsEnable = true;
 mySerialPort.ReadBufferSize = 32768;

属性值 类型:System.Int32 缓冲区大小,以字节为单位。默认值为 4096;最大值是正整数,或 2147483647

然后在 Python 中打开并使用

于 2018-04-24T21:47:56.633 回答
0

令我有些惊讶的是,尚未有人提及此类问题的正确解决方案(如果可用),即通过软件 (XON/XOFF) 或微控制器与其接收器之间的硬件流控制进行有效的流控制。这篇网络文章很好地描述了这个问题。

可能是源设备不支持此类协议,在这种情况下,您会遇到一系列解决方案,这些解决方案将问题向上委托给更多可用资源的地方(将其从 UART 缓冲区移动到驱动程序并向上移动到您的应用代码)。如果您正在丢失数据,那么在可能的情况下尝试实施较低的数据速率当然是明智的。

于 2019-04-17T07:52:39.907 回答
0

对我来说,问题是从 Arduino 接收数据时缓冲区过载。我所要做的就是mySerialPort.flushInput()它奏效了。

我不知道为什么mySerialPort.flush()没有工作。flush()必须只刷新传出数据?

我所知道的只是mySerialPort.flushInput()解决了我的问题。

于 2021-04-29T12:08:28.383 回答