我正在通过串口读取微控制器的数据,波特率为921600.我正在读取大量的ASCII csv数据,因为它的速度非常快,所以缓冲区得到了填充,所有其余的数据在我阅读它之前迷路了。我知道我可以手动编辑serialwin32的pyserial源代码以增加缓冲区大小,但我想知道是否还有其他方法呢?
我只能估计我将收到的数据量,但它大约有200kB的数据。
答案 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端口的属性页访问“接收缓冲区”滑块。可以通过“端口设置”选项卡上的“高级”按钮找到它。
更多信息:
标题接收缓冲区 下的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()
解决了我的问题。