Matlab 中的串行通信非常慢。有办法加快速度吗?
我在 Matlab 中编写了一个用于串行通信(RS232)的程序,该程序应该与微处理器进行通信。它可以很好地接收数据,但发送数据时,2 个字节的数据需要 0.2-0.5 秒。有没有一种已知的方法可以加速 Matlab 中的串行通信,或者我必须忍受这个?
这是我用来编写的代码:
% confa serieporten
com_port = '/dev/tty.FireFly-16CB-SPP';
ser = serial(com_port, 'BaudRate', 115200);
ser.BytesAvailableFcnCount = 1;
ser.BytesAvailableFcnMode = 'byte';
ser.Timeout = 5;
i = 1;
while i <=length(buffer)
fwrite(ser, buffer(i));
i = i + 1;
end
I've written a program for some serial communication (RS232) in Matlab that's supposed to communicate with an microprocessor. It works fine receiving data from it, but when sending data it takes between 0.2-0.5 seconds for 2 bytes of data. Is there a known way to speed up serial communications in Matlab or will I have to live with this?
Here is the code I'm using for writing:
% confa serieporten
com_port = '/dev/tty.FireFly-16CB-SPP';
ser = serial(com_port, 'BaudRate', 115200);
ser.BytesAvailableFcnCount = 1;
ser.BytesAvailableFcnMode = 'byte';
ser.Timeout = 5;
i = 1;
while i <=length(buffer)
fwrite(ser, buffer(i));
i = i + 1;
end
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先,在进行任何优化之前,您应该进行分析。
打开 Matlab profiler,运行您的程序并发现瓶颈所在。
First of all, before doing any optimization, you should do profiling.
Open the Matlab profiler, run your program and discover where the bottleneck is.
我非常确定 SERIAL 对象正在使用 Java API(至少以前是这样;自从我使用它以来,实现可能已经发生了变化)。与在 MATLAB 中“直接”与 Java 对象通信相比,使用 MATLAB 对象系统的开销是微不足道的。因此,我不会费心尝试跳过 SERIAL 对象并“直接使用 Java”。
我向您提出的问题是,“您必须尝试立即发送每个字节吗?”如果您使用较大的 BytesAvailableFcnCount 值,通信会更加高效。
除非您的硬件有非常特殊的限制,否则我建议选择更大的缓冲区大小。 (这可能要求您在数据流结束时强制刷新,因为您不能指望自动写入每个字节。但大概您已经在适当的时间关闭并删除了该对象,因此同时另外刷新缓冲区应该不难)。
如果您不指定值,MATLAB 将使用默认值 48 字节。我不记得如何选择这个确切的值,但是一次写入多个值比写入缓冲区并一次刷新一个字节要高效得多。
编辑:另一个想法;我现在没有 MATLAB 来测试这个,但是如果您不在
for
循环中写入数据 - 相反,保留BytesAvailableFcnCount
设置为 1,然后一次性写入整个缓冲区?我阅读文档的方式,
BytesAvailableFcnCount
仅指定缓冲区在刷新之前可以达到多大的“触发器”,而不指定缓冲区可以有多大。因此,如果BytesAvailableFcnCount
为 1 并一次性写入大小为 128 的缓冲区,可能只会刷新到设备一次,而不是现有的 128 次代码确实如此。I'm pretty certain that the SERIAL object is using the Java APIs (at least, it used to; the implementation may have changed since I've worked with it). The overhead of using the MATLAB object system, as opposed to talking to the Java objects "directly" in MATLAB, is trivial. Therefore, I wouldn't bother to try skipping the SERIAL object and going to "straight to Java."
My question back to you is, "Do you have to attempt to send every byte immediately?" The communication should be much more efficient if you use a larger value for
BytesAvailableFcnCount
.Unless your hardware has very particular constraints, I recommend choosing a larger buffer size. (This may require you to forcibly flush when the data stream ends, since you can't count on very byte being written automatically. But presumably, you're already closing and deleting the object at the appropriate time, so it shouldn't be hard to additionally flush the buffer simultaneously).
If you don't specify a value, MATLAB uses a default value of 48 bytes. I don't recall how that exact value was chosen, but writing several values at once will be much more efficient than writing to the buffers and flushing them a byte at a time.
EDIT: Another thought; I don't have a MATLAB to test this with right now, but what happens if you don't write the data in a
for
loop - instead, leave theBytesAvailableFcnCount
set to 1, and fwrite the entire buffer in one shot?The way that I read the documentation,
BytesAvailableFcnCount
only specifies the "trigger" for how large the buffer can get before its flushed, not how large the buffer can be. So having aBytesAvailableFcnCount
of 1 and writing to a buffer of size (say) 128 in one shot might flush to the device only once, instead of 128 times, which your existing code does.