App Designer: Arduino GUI crashes when live-plotting IMU orientation data in a poseplot.

6 views (last 30 days)
I'm building a GUI with the Matlab App Designer which incorporates three hall-effect sensors and a lsm9ds1 IMU built onto an Arduino Uno. The code snags after running for 5 seconds and does not give me an error message. I've built a while loop that stops when the 'Stop' button is pressed and the system has a 'Reset' button to re-calibrate the imu when in its starting position (to account for sensor inaccuracies). The hall effect sensors are hooked on the three principal axes and form a vector in a specific direction which is also live-plotted onto the orientation plot. For the orientation plot I use poseplot() and for the vector I use quiver3(). I load both objects when the window opens and edit their respective direction/orientation properties in the while loop (instead of reloading the objects every iteration of the while loop).
The problem arises when I try to streamline the code. At first I wrote a bulky code which drags its feet, leading to a jumpy feed as the orientation of the IMU is changed. The first change I tried was to read the IMU data with 1 line of code instead of 3 (see the first section after the tic command). This works fine for the first few seconds, then the code stops working. My while loop is as follows:
while ~app.stop
tic
% Read imu sensor data and flush unnecesary data
%accel = readAcceleration(app.imu1);
%gyro = readAngularVelocity(app.imu1);
%magn = readMagneticField(app.imu1);
[accel,gyro,magn] = read(app.imu1);
flush(app.imu1);
% Fuse sensor data into quaternions and rotation matrix
FUSE = ahrsfilter('SampleRate', app.imu1.SampleRate);
app.q = FUSE(accel,gyro,magn);
rotators = app.qzero+app.q;
rotmat = quat2rotm(rotators);
% Read voltages of Hall effect sensors
v_z = (readVoltage(app.a,"A0")-z_offset)*150; % z-axis
v_x = (readVoltage(app.a,"A1")-x_offset)*150; % x-axis
v_y = (readVoltage(app.a,"A2")-y_offset)*150; % y-axis
voltages = [v_z;v_y;v_x];
local = rotmat*voltages;
% Update poseplot (box) and quiver3 (quiv) objects with new data
app.quiv.UData = local(3);
app.quiv.VData = local(2);
app.quiv.WData = local(1);
app.box.set(Orientation=rotators);
% Update Hall effect plots animatedline per direction
t = datetime("now")-startTime;
addpoints(app.Va_x,datenum(t),local(3)) % X-direction
addpoints(app.Va_y,datenum(t),local(2)) % Y-direction
addpoints(app.Va_z,datenum(t),local(1)) % Z-direction
% Remove data points from animatedline after 20 seconds
app.Va_xplot.XLim = datenum([t-seconds(20) t]);
app.Va_yplot.XLim = datenum([t-seconds(20) t]);
app.Va_zplot.XLim = datenum([t-seconds(20) t]);
% Show live data values in specific directions from Hall effect sensors
app.EditField.Value = local(3); % X-direction
app.EditField_2.Value = local(2); % Y-direction
app.EditField_3.Value = local(1); % Z-direction
app.LoopSpeedEditField.Value = toc;
end
My question is more along the lines of how do I ensure a fast refresh rate (short loop runtime) while not causing the code to crash or incurring matlab buffer storage errors? I've moved constant variables to outside of the while loop and switched to quaternions, but the first block of code (the IMU sensor reading bit) trips up the whole thing.

Accepted Answer

Ryan Salvo
Ryan Salvo on 20 May 2022
Edited: Ryan Salvo on 24 May 2022
Hi Floris-Jan Nieuwenhuis,
In your current while loop, you can further optimize the code by creating the ahrsfilter object outside of the loop, then passing the new IMU data to it during each iteration of the loop. This example shows how to use the ahrsfilter object in this way.
For further optimization, try to use the MATLAB Profiler to determine the section of code that is causing the most slowdown. There are some Related Topics on that page that should help with improving the code performance.
Thanks,
Ryan
  4 Comments
Floris-Jan Nieuwenhuis
Floris-Jan Nieuwenhuis on 25 May 2022
Adding a tune object function slows down the loop speed, even if it has just one iteration. I have noticed, however, that using:
[accel,gyro,magn] = read(app.imu1);
Instead of:
accel = readAcceleration(app.imu1);
gyro = readAngularVelocity(app.imu1);
magn = readMagneticField(app.imu1);
is faster. The only issue is that the code stops itself due to the error "Receive on demand storage buffer is full" at a readVoltage command. What's causing this?
Floris-Jan Nieuwenhuis
Floris-Jan Nieuwenhuis on 27 May 2022
I'm fairly certain it has something to do with the read(app.imu1) command. When I try to run it in the command prompt I get a warning saying:
"Warning: MATLAB buffers are flushed to get latest values."
Then it returns a partial answer of three values when it should provide a 3x3 matrix of 9 values (since it 'OutputFormat' is configured to 'matrix').

Sign in to comment.

More Answers (0)

Products


Release

R2021b

Community Treasure Hunt

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

Start Hunting!