使用 matlab fscanf() 或 fgetl() 读取串行端口显示实际值更改后几秒的结果
Reading serial port with matlab fscanf() or fgetl() shows results seconds after actual value change
我正在使用 Arduino 的模拟引脚测量电压并使用 serial.print(string)
将其打印到串行端口。这是有效的,它以 xxxx.yyyy
的形式输出一个不同长度的值,这是我在串行查看器中检查过的。为了阅读它,我使用 Matlab 和 fscanf()
或 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 line
和 addpoints
。
最后,您可能需要检查几件事情:串行端口上的 Arduino connection for Matlab (I never tried it myself but I've read it gives good performance) and the latency timer(这可能会在低波特率下产生影响)。
我正在使用 Arduino 的模拟引脚测量电压并使用 serial.print(string)
将其打印到串行端口。这是有效的,它以 xxxx.yyyy
的形式输出一个不同长度的值,这是我在串行查看器中检查过的。为了阅读它,我使用 Matlab 和 fscanf()
或 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 line
和 addpoints
。
最后,您可能需要检查几件事情:串行端口上的 Arduino connection for Matlab (I never tried it myself but I've read it gives good performance) and the latency timer(这可能会在低波特率下产生影响)。