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

조회 수: 4 (최근 30일)
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

채택된 답변

Madheswaran
Madheswaran 2024년 12월 26일
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
Walter Roberson
Walter Roberson 2024년 12월 27일
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 2024년 12월 27일
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.

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Adam Danz
Adam Danz 2024년 12월 26일
편집: Adam Danz 2024년 12월 26일
> 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
Andrew Tilmouth
Andrew Tilmouth 2024년 12월 27일
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 2024년 12월 27일
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

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Migrate GUIDE Apps에 대해 자세히 알아보기

제품


릴리스

R2022a

Community Treasure Hunt

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

Start Hunting!

Translated by