matlab - 使用 matlab fscanf() 或 fgetl() 读取串行端口会在实际值更改后数秒显示结果
问题描述
我正在使用 Arduino 的模拟引脚来测量电压并将其打印到带有serial.print(string)
. 这是有效的,它以不同长度的形式输出一个值xxxx.yyyy
,我用内置的串行查看器检查了这一点。要阅读它,我将Matlab与fscanf()
or结合使用fgetl()
。这显示了正确的东西,aaaa.bbbb
但是有一种奇怪的延迟。当我改变电压时,读数会滞后 5-10 秒,但是当我将电压从 0 增加到 3 到 5 时,在此timeframe
期间,例如 3 到 5 之间的 3 秒,读数也会发生变化。它与我更改电压的方式不同,但它确实获得了这些值,就好像它是 2 步输入一样,即使我手动更改它们的速度不是很快。
在阅读和研究时,我发现可能是波特率太低,所以我将其更改为 Arduino 的最大值 115200。我也更改了Matlab代码中的值。我还尝试了具有该功能的 Arduino 硬件支持包,readVoltage()
但它的采样率太低。
串口设置:
s = serial('com3');
set(s, 'BaudRate', 115200); % set BaudRate to 115200
set(s, 'Parity', 'none'); % set Parity Bit to None
set(s, 'DataBits', 8); % set DataBits to 8
set(s, 'StopBit', 1); % set StopBit to 1
set(s,'Terminator','LF') % set terminating character to LF/new line
fopen(s);
阅读循环:
for i =1:am
val(:,i) = string(fgetl(s)); %retrieve value of serial port, in the form aaaa.bbbb where a and b can vary in length
if mod(i,10) == 0 %Display every 10 iterations
volt1 = floor(val)*5/1023; %Calculating actual voltage for A1, where floor(val) is first value
volt2= (volt1-floor(val))*5/0.1023; %getting only decimals for second voltage
plot(volt1) %plot the values
hold on
plot(volt2)
hold off
ylim([0 5])
xlim([i-1000 i]) %make the plot chug along
drawnow %Live
end
clc
toc
end
没有错误消息,并且使用另一个串行端口,我没有明显的延迟。这也应该可以使用 Matlab,因为人们使用它可以获得 2-3kHz 的刷新率。
解决方案
问题是您plot
在循环中使用的方式。这是非常低效的。
根据您的 Matlab 版本和串行链接上的开销,您可能能够加快clf
循环开始时的调用速度,以防止大量图相互堆叠。
如果问题仍然存在,您可能想尝试animated line
并addpoints
在循环中。
最后,您可能需要检查几件事:Matlab 的Arduino 连接(我自己从未尝试过,但我读过它提供了良好的性能)和串行端口上的延迟计时器(这可能会产生影响在低波特率)。