Plotting in a parallel while reading serial

2 次查看(过去 30 天)
Hi there,
I have the following code (which I have simplified a bit to post).
It captures the position and force from a test rig, which I am printing out over serial as fast as possible and reading into matlab.
It grabs the most recent reading from each serial device and stores it along with the current time (using tic toc).
I then plot this data on a graph.
My problem is that while matlab is executing the plot I miss some new incoming serial data and build up a back log.
I have improved the situation by only plotting every 50 times i collect data, but this still allows a buildup to occur during plotting. Can i carry out the plot in a parallel thread to avoid affecting the serial reads? How would i structure this?
Thanks!
positioncounter=0;
forcecounter=0;
tic
while running==1
if rig.bytesavailable>0 %grab rig position and time
positioncounter=positioncounter+1;
position = fscanf(rig);
ResultsPosition(positioncounter,1)= toc;
ResultsPosition(positioncounter,2)=str2double(position(1:end-2));
end
if s.bytesavailable>0 %grab force and time
forcecounter=forcecounter+1;
force = fscanf(s);
ResultsForce(forcecounter,2)=9.81*str2double(force(1:end-2));
ResultsForce(forcecounter,1)= toc;
end
try
yyaxis left
plot(ResultsForce(:,1),ResultsForce(:,2));
yyaxis right
plot(ResultsPosition(:,1),ResultsPosition(:,2));
end
running =get(handles.BTN_CAPTURE,'Value'); %is button still toggled on
drawnow();
end
  8 个评论
Walter Roberson
Walter Roberson 2019-6-8
Are you using true serial, or are you using serial over USB ?
There is an arduino-like device that sends data direct to USB instead of buffering it, and so can achieve higher data rates. Unfortunately I keep losing track of which device it is.
Adam
Adam 2019-6-10
Do you need or want every point to be its own plot, as is in your code included in the question? This is, in general, an expensive way to plot data. Much more efficient is to create one plot and then edit its XData and YData properties to add your new data.
e.g.
yyaxis left
hPlotForce = plot(ResultsForce(:,1),ResultsForce(:,2));
yyaxis right
hPlotPosition = plot(ResultsPosition(:,1),ResultsPosition(:,2));
for the first point, then
set( hPlotForce, 'XData', [ hPlotForce.XData, ResultsForce(:,1) ], 'YData', [ hPlotForce.YData, ResultsForce(:,2) ] );
set( hPlotPosition, 'XData', [ hPlotPosition.XData, ResultsPosition(:,1) ], 'YData', [ hPlotPosition.YData, ResultsPosition(:,2) ] );
on each subsequent pass.
Normally I do this by storing a handle to the initially empty plot e.g.
hPlotForce = [];
then in my code I have an if else
if isempty( hPlotForce )
...
else
...
end
where the first code above goes in the if and the second block of code in the else - i.e. if the plot hasn't been created yet then call plot, if it has then edit the existing plot.
Sometimes simply speeding up the way you plot solves the problems itself without you needing to come up with complex parallelisation. It may not in this case, I don't know, but calls to plot are expensive and create a new graphics object every time and the more individual graphics objects you have the slower your code is generally.

请先登录,再进行评论。

回答(0 个)

类别

Help CenterFile Exchange 中查找有关 Graphics Objects 的更多信息

产品


版本

R2018b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by