how to halt a for loop in an external function called from mlapp by using a stop button in the mlap app

5 views (last 30 days)
I have an mlapp UI, it has a "run real time process button" when the button is pressed it runs an m file function in the same directory. For now the function is a for loop processing many arrays of pressure data (it is intended these will be replaced with continuous pressure data from a Nat Instruments USB6212 which is why i would like to have a stop button to exit gracefully and save a file of data). I have put a stop button on the mlapp UI. I have followed this thread https://au.mathworks.com/matlabcentral/answers/583796-app-designer-terminate-an-execution-of-a-function#answer_484307 but I am missing something
In mlapp I have declared the stop flag as public
properties (Access = public)
stopFlag % stop flag linked to Stop button to halt real time code
end
In mlapp I have intitialised the flag to false:-
% Code that executes after component creation
function startupFcn(app)
% init the stop button stopFlag to false
app.stopFlag = false;
end
In mlapp I have set the flag to true if the stop button is pushed:-
% Button pushed function: StopCombustionAnalyserButton
function StopCombustionAnalyserButtonPushed(app, event)
app.stopFlag = true; % on Stop button press set stopFlag to true
end
In the function that is called from mlab when the "start processing data" button is pushed on the mlapp ui I have added this code in the for loop:-
if app.stopFlag % halt combustion analysis if Stop button is pressed
return
end
But when I run the function (for loop) via the "start processing button" it errors at the line "if app.stopFlag"
with
"Unable to resolve the name 'app.stopFlag'."
I don't understand what is missing, should I be able to see app.stopFlag in the workspace of the external function? Surely if app.stopFlag is not in the functions worksapce then the if statement won't work.
Do I need to pass in app.stopFlag as an argument with the function when I call it, I thought that making app.stopFlag public would mean no, also passing it in once when I call the function probably is not the answer anyway.
Could anyone or @Adam Danz calrify where i am going wrong, thanks

Accepted Answer

Madheswaran
Madheswaran on 26 Dec 2024
Hi Andrew,
The error occurs because MATLAB functions can't automatically access properties of the App object unless you explicitly pass the 'app' object to them. Even though 'stopFlag' is declared as public, the external function has no way to know which App instance it should reference.
To resolve this error, pass the 'app' object when calling the function. Below code illustrates this workflow:
% In your app start button callback / wherever the external function is
% called
processData(app); % Pass the app object to external function
And in the external function, take 'app' as parameter:
function processData(app)
if app.stopFlag
return;
end
% ... existing code
end
This way, the external function will have access to 'stopFlag'.
Hope this helps!
  3 Comments
Walter Roberson
Walter Roberson on 27 Dec 2024
The loop needs to have one of:
  • pause()
  • drawnow()
  • waitfor()
  • uiwait()
  • figure()
  • keyboard()
in order to be able to process the button press or key press events.
Button press and key press events are not asynchronous in MATLAB: they are only polled for when one of the above are called.
Andrew Tilmouth
Andrew Tilmouth on 27 Dec 2024
Hi Walter, awesome I added drawnow after one of the addpoints figure updates in the loop and it is immediately responsive to the Stop button, thanks very much.

Sign in to comment.

More Answers (1)

Adam Danz
Adam Danz on 26 Dec 2024
Edited: Adam Danz on 26 Dec 2024
> Do I need to pass in app.stopFlag as an argument with the function when I call it, I thought that making app.stopFlag public would mean no
Setting stopFlag as public means that the app.stopFlag variable is avaiable outside of the app but it's still stored in the app object.
You want to pass the app handle into your external function. Any time your function accesses app.stopFlag it will retreive the current state.
Also, if you're using a StateButton, you don't need the StopCombustionAnalyserButtonPushed function or the stopFlag property. Instead, just check the state of the button using the Value property.
  1. Add a StateButton named "Stop" (or whatever you want to name it). The button handle will already be public.
  2. Initialize the button's state as off, app.StopButton.Value=false
  3. Pass the app object into your external function.
  4. Instead of using if app.stopFlag, use if app.StopButton.Value
  2 Comments
Andrew Tilmouth
Andrew Tilmouth on 27 Dec 2024
Hi Adam, thanks for your feedback, I have implemented the StateButton instead as it is cleaner. But as per my reply above to Madheswaran the stop button is unresponsive when the for loop is running unless I add a pause which I dont want to do. So now I am wodnering can this be done in Matlab, is this some kind of threading issue?, do you have to have the parallel computing tool box for this kind of thing to work properly?. thanks Andrew
Adam Danz
Adam Danz on 27 Dec 2024
pause isn't the most efficient of the options listed. I would use drawnow limitrate which limits the number of updates to a maximum of 20 per second and skips updates when the renderer is busy. Unless you are producing graphics within the loop, adding this should be nearly inconsequential to performance.
If your loop is fast and you want to limit the number of updates even further, you could use tic/toc or a timer object to control the frequency. For example, drawnow is called approximatesly every 1 second in the loop below.
t0 = tic();
while true
if toc(t0)>1
drawnow
end
end

Sign in to comment.

Categories

Find more on Migrate GUIDE Apps in Help Center and File Exchange

Products


Release

R2022a

Community Treasure Hunt

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

Start Hunting!