使用 matlab fscanf() 或 fgetl() 读取串行端口显示实际值更改后几秒的结果

Reading serial port with matlab fscanf() or fgetl() shows results seconds after actual value change

我正在使用 Arduino 的模拟引脚测量电压并使用 serial.print(string) 将其打印到串行端口。这是有效的,它以 xxxx.yyyy 的形式输出一个不同长度的值,这是我在串行查看器中检查过的。为了阅读它,我使用 Matlabfscanf()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 版本和序列号 link 的开销,您可以加快在循环开始时调用 clf 的速度,以防止大量绘图堆积彼此之上。

如果问题仍然存在,您可能想在循环中尝试 animated lineaddpoints

最后,您可能需要检查几件事情:串行端口上的 Arduino connection for Matlab (I never tried it myself but I've read it gives good performance) and the latency timer(这可能会在低波特率下产生影响)。