Pyserial缓冲区的填充速度比我读的要快

时间:2012-04-12 13:53:11

标签: python serial-port pyserial

我正在通过串口读取微控制器的数据,波特率为921600.我正在读取大量的ASCII csv数据,因为它的速度非常快,所以缓冲区得到了填充,所有其余的数据在我阅读它之前迷路了。我知道我可以手动编辑serialwin32的pyserial源代码以增加缓冲区大小,但我想知道是否还有其他方法呢?

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

5 个答案:

答案 0 :(得分:5)

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

这将在写入命令和开始读取之后消除一些延迟。有other SO users成功使用此方法,授予他们没有缓冲区溢出。

如果不清楚,请告诉我,我可以将一些东西放在一起展示。

修改

考虑一下,如果你试图从缓冲区读取并将其写入文件系统,即使是独立的线程也可能无法保存。为了最大限度地缩短处理时间,您可以考虑一次读取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;

答案 1 :(得分:4)

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

advanced settings for com port

更多信息:

标题接收缓冲区

下的

http://support.microsoft.com/kb/131016 标题中断

下的

http://tldp.org/HOWTO/Serial-HOWTO-4.html

尝试将它击倒一两档。

答案 2 :(得分: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中打开并使用它

答案 3 :(得分:0)

令我有些惊讶的是,还没有人提到针对此类问题的正确解决方案(如果可用),即通过软件(XON / XOFF)或微控制器及其接收器之间的硬件流控制进行有效的流控制。 this web article对问题进行了很好的描述。

可能是源设备不遵守此类协议,在这种情况下,您会陷入一系列将问题向上委派给更多资源的解决方案中(将其从UART缓冲区移至驱动程序,然后朝您的应用程序代码)。如果您正在丢失数据,那么如果可能的话,尝试实施较低的数据速率似乎是明智的。

答案 4 :(得分:0)

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

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

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