Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
Push button to halt a loop

Subject: Push button to halt a loop

From: Frank

Date: 30 May, 2011 06:17:02

Message: 1 of 12

Hello.

Is there a way to code up a GUI that gracefully brings a program out of a loop (i.e to avoid using Ctrl + C)?
Something like:

a = 1;

while a ==1
...run and plot this...
'GUI code which sets a=0 when button is pressed' (thus ending the loop).
end

I'm trying to find a way to run a program indefinitely until a key/button is pressed.

Subject: Push button to halt a loop

From: Rune Allnor

Date: 30 May, 2011 06:22:58

Message: 2 of 12

On May 30, 8:17 am, "Frank " <thegu...@hotmail.com> wrote:
> Hello.
>
> Is there a way to code up a GUI that gracefully brings a program out of a loop (i.e to avoid using Ctrl + C)?
> Something like:
>
> a = 1;
>
> while a ==1
> ...run and plot this...
> 'GUI code which sets a=0 when button is pressed' (thus ending the loop).
> end
>
> I'm trying to find a way to run a program indefinitely until a key/button is pressed.

You don't really want to do that, but the way to achieve
this is to start the GUI component where the button appears
before you enter the loop, and then poll the state of the
button in each iteration of the loop.

Rune

Subject: Push button to halt a loop

From: Nasser M. Abbasi

Date: 30 May, 2011 06:38:47

Message: 3 of 12

On 5/29/2011 11:17 PM, Frank wrote:
> Hello.
>
> Is there a way to code up a GUI that gracefully brings a program out of a loop
>(i.e to avoid using Ctrl + C)?
> Something like:
>
> a = 1;
>
> while a ==1
> ...run and plot this...
> 'GUI code which sets a=0 when button is pressed' (thus ending the loop).
> end
>
> I'm trying to find a way to run a program indefinitely until a key/button is pressed.

Yes, ofcourse, I do that all the time. Very easy, like this:

have a STOP button. In its call back, read your userData struct
from figure (doc userData), which you'd already set up, and
set a flag in it to true, say STOP=true. Then save the userData
back.

The mainline (your loop), will, at the end of each iteration,
read userData and checks if the flag is true of false, if it
is true, it terminates the loop, and sets the flag to false
to be ready for the next time the mainline is called,
and then write userData back to figure. Something like

  moreWork = true;
  while moreWork

     .... busy work here
     .... if done, moreWork=false;

     %check if user hit STOP button
     userData = get(handles.figure1, 'UserData');
     if userData.state == STOP
        userData.state = RUN; %reset for next time
        set(handles.figure1,'UserData',userData);
        moreWork = false; %to stop the loop
     end
end


Do not need to worry about race conditions between Stop button
callback and mainline, as main line will be interrupted untill
stop button callback is completed (matlab takes care of this).

Initially, in your GUI OpeningFcn (if you are using GUIDE), you'll
set up the userData struct and init this flag to false.

--Nasser

Subject: Push button to halt a loop

From: Nasser M. Abbasi

Date: 30 May, 2011 06:56:56

Message: 4 of 12


I thought maybe I should re-write this again to include the
whole setup to make things more clear.

In OpeningFcn(), if using GUIDE, do
-------------------------------------------
   set(handles.figure1, 'UserData',[]);
   userData.stop = false;
   set(handles.figure1, 'UserData',userData);

In the STOP button callback, do (this is the interrupt)
-----------------------------------
    userData = get(handles.figure1, 'UserData');
    userData.stop = true;
    set(handles.figure1,'UserData',userData);


In the mainline, (the RUN button callback) do
---------------------------------------------

     moreWork = true;
     while moreWork
  
        .... busy work here
        .... if done, moreWork=false;
  
         %check if user hit STOP button
         userData = get(handles.figure1, 'UserData');
         if userData.stop == true
            userData.stop = false; %reset for next time
            set(handles.figure1,'UserData',userData);
            moreWork = false; %to stop the loop
         end
     end

  
--Nasser

Subject: Push button to halt a loop

From: Frank

Date: 1 Jun, 2011 01:21:02

Message: 5 of 12

Thanks Nasser for you're fast response.

Subject: Push button to halt a loop

From: Azimut

Date: 17 Jan, 2012 14:08:09

Message: 6 of 12

"Frank" wrote in message <is445u$qhn$1@newscl01ah.mathworks.com>...
> Thanks Nasser for you're fast response.

Sorry, Nasser:

I tried something like what you suggested. Actually I did it almost the same way before reading your post. With no success. To me this does not work.

The main loop always takes control until the simulation is done. The stop callback is queued and acts only after the main loop terminates. I am not able to find a workaround.

Am I missing anything?

Subject: Push button to halt a loop

From: Nasser M. Abbasi

Date: 17 Jan, 2012 14:30:07

Message: 7 of 12

On 1/17/2012 8:08 AM, Azimut wrote:
> "Frank" wrote in message<is445u$qhn$1@newscl01ah.mathworks.com>...
>> Thanks Nasser for you're fast response.
>
> Sorry, Nasser:
>
> I tried something like what you suggested. Actually I did it almost the same way
>before reading your post. With no success. To me this does not work.
>
> The main loop always takes control until the simulation is done. The stop callback
>is queued and acts only after the main loop terminates. I am not able to find a workaround.
>
> Am I missing anything?

humm.. I am sorry, I have no idea what are you refering to. I see
nothing in this message I can respond to.

--Nasser

Subject: Push button to halt a loop

From: Azimut

Date: 17 Jan, 2012 15:07:09

Message: 8 of 12

The point is that the structure you suggested:

run_Callback
    userData = get(handles.figure1, 'UserData');
    if (userData.stop == true)
        userData.stop = false; %reset for next time
        set(handles.figure1,'UserData',userData);
        abort_simulation;
    end
simulation_loop;

stop_Callback %pushbutton
userData = get(handles.figure1, 'UserData');
userData.stop = true;
set(handles.figure1,'UserData',userData);

practically does not work, even though it should. Matlab apparently is not able to get the status update from "stop callback", perhaps because too busy with simulating the intensive "simulation_loop" called from "run_Callback".

However I found a trick to give Matlab time to check stop_Callback updates.
The code example above works if a statement like: pause(0.000001) is placed among run_Callback instructions.

(I found this trick in another thread, not my idea; at least in my case it works)

Subject: Push button to halt a loop

From: Nasser M. Abbasi

Date: 17 Jan, 2012 15:34:42

Message: 9 of 12

On 1/17/2012 9:07 AM, Azimut wrote:
> The point is that the structure you suggested:
>
> run_Callback
> userData = get(handles.figure1, 'UserData');
> if (userData.stop == true)
> userData.stop = false; %reset for next time
> set(handles.figure1,'UserData',userData);
> abort_simulation;
> end
> simulation_loop;
>
> stop_Callback %pushbutton
> userData = get(handles.figure1, 'UserData');
> userData.stop = true;
> set(handles.figure1,'UserData',userData);
>
> practically does not work, even though it should. Matlab apparently is
>not able to get the status update from "stop callback", perhaps because
>too busy with simulating the intensive "simulation_loop" called from "run_Callback".
>
> However I found a trick to give Matlab time to check stop_Callback updates.
> The code example above works if a statement like: pause(0.000001) is placed among run_Callback instructions.
>
> (I found this trick in another thread, not my idea; at least in my case it works)

First, I am glad things worked for you.

Second, I have no clue where the above code with 'abort_simulation' came
from, becuase I did not write that. Here is the link:

http://www.mathworks.com/matlabcentral/newsreader/view_thread/308463

Third, I gave you a pattern to follow, a general approach. I did not include
all the details and every thing. If you asked for more details, I would have
given you a link to an example code I did, here is one

Here is just one example showing how it works

http://12000.org/my_courses/UC_davis/spring_2011/MAE_121_eng_dynamics/lab/lab_one/index.htm

click on the HTML link there, and click on the source code. And yes, I did
use a pause for tiny amount to get this to run, I never said I did not as I was
just giving you a pattern, not an actual code with all the details. I did
not think I had to include every bit of everything each time I answer something.

But it is not important now. Since it works for you know.

--Nasser

Subject: Push button to halt a loop

From: Sung Soo Kim

Date: 25 Jan, 2012 22:26:10

Message: 10 of 12

Instead of "pause(0.0001)", use "drawnow;". "pause" command is extremely slow because it uses very inaccurate timing mechanism. If you're running a time-critical loop, NEVER use "pause" in your loop. Having said that, drawnow is not a perfect choice either. However, there is no delay. Only the overhead to process "drawnow" exists. So, if you're not running many GUI objects doing this and that, "drawnow" exits fairly well. In a very fast computer you may finish "drawnow" within 0.1ms, which is good for usual task.

Best,


"Azimut" wrote in message <jf42qt$8ni$1@newscl01ah.mathworks.com>...
> The point is that the structure you suggested:
>
> run_Callback
> userData = get(handles.figure1, 'UserData');
> if (userData.stop == true)
> userData.stop = false; %reset for next time
> set(handles.figure1,'UserData',userData);
> abort_simulation;
> end
> simulation_loop;
>
> stop_Callback %pushbutton
> userData = get(handles.figure1, 'UserData');
> userData.stop = true;
> set(handles.figure1,'UserData',userData);
>
> practically does not work, even though it should. Matlab apparently is not able to get the status update from "stop callback", perhaps because too busy with simulating the intensive "simulation_loop" called from "run_Callback".
>
> However I found a trick to give Matlab time to check stop_Callback updates.
> The code example above works if a statement like: pause(0.000001) is placed among run_Callback instructions.
>
> (I found this trick in another thread, not my idea; at least in my case it works)

Subject: Push button to halt a loop

From: ScottB

Date: 25 Jan, 2012 23:27:09

Message: 11 of 12

"Frank" wrote in message <irvcou$hv$1@newscl01ah.mathworks.com>...
> Hello.
>
> Is there a way to code up a GUI that gracefully brings a program out of a loop (i.e to avoid using Ctrl + C)?
> Something like:
>
> a = 1;
>
> while a ==1
> ...run and plot this...
> 'GUI code which sets a=0 when button is pressed' (thus ending the loop).
> end
>
> I'm trying to find a way to run a program indefinitely until a key/button is pressed.

function rotate_triangle()
axes('units','normalized',...
     'position',[0.1 0.1 0.8 0.8],...
     'color',[0.5 0.5 0.5],...
     'NextPlot','replacechildren',...
     'tag','plot_axes');
hp = plot([1 3 2 1],[2 4 1 2]);
set(hp,'tag','tplot');
xlim([-8 8]);
ylim([-8 8]);
% define rotation button
uicontrol('units','normalized',...
    'position', [0.42 .925 .15 .05],...
    'style','push',...
    'SelectionHighlight','off',...
    'string','rotate',...
    'fontweight','bold',...
    'fontsize', 10,...
    'fontname','arial',...
    'foregroundcolor',[0 0 0],...
    'callback',{@rotate_button},...
    'tag','rotate_button');

function rotate_button(hload,eventdata)
% locate and delete the main figure object
ax = findobj('tag','plot_axes');
hp = findobj('tag','tplot');
hb = findobj('tag','rotate_button');
stop_flag = get(hp,'userdata');
if ~isempty(stop_flag)
    if stop_flag == 0
        set(hp,'userdata',1)
        set(hb,'string','rotate');
    elseif stop_flag == 1
        set(hp,'userdata',0);
        set(hb,'string','stop');
    end
else
    set(hp,'userdata',0)
    set(hb,'string','stop');
end
t = hgtransform('Parent',ax);
set(hp,'Parent',t)
Rz = eye(4);
for r = 0:.1:2000*pi
    Rz = makehgtform('zrotate',r);
    set(t,'Matrix',Rz)
    drawnow
    pause(0.01)
    stop_flag = get(hp,'userdata');
    if stop_flag == 1
        break
    end
end
return

Subject: Push button to halt a loop

From: Azimut

Date: 26 Jan, 2012 09:16:09

Message: 12 of 12

Thanks, Sung Soo.

drawnow is perfect for my purpose.
I think the picture is complete now.

best regards, A.



"Sung Soo Kim" <sskimbox@aol.com> wrote in message <jfpvi2$b50$1@newscl01ah.mathworks.com>...
> Instead of "pause(0.0001)", use "drawnow;". "pause" command is extremely slow because it uses very inaccurate timing mechanism. If you're running a time-critical loop, NEVER use "pause" in your loop. Having said that, drawnow is not a perfect choice either. However, there is no delay. Only the overhead to process "drawnow" exists. So, if you're not running many GUI objects doing this and that, "drawnow" exits fairly well. In a very fast computer you may finish "drawnow" within 0.1ms, which is good for usual task.
>
> Best,
>
>
> "Azimut" wrote in message <jf42qt$8ni$1@newscl01ah.mathworks.com>...
> > The point is that the structure you suggested:
> >
> > run_Callback
> > userData = get(handles.figure1, 'UserData');
> > if (userData.stop == true)
> > userData.stop = false; %reset for next time
> > set(handles.figure1,'UserData',userData);
> > abort_simulation;
> > end
> > simulation_loop;
> >
> > stop_Callback %pushbutton
> > userData = get(handles.figure1, 'UserData');
> > userData.stop = true;
> > set(handles.figure1,'UserData',userData);
> >
> > practically does not work, even though it should. Matlab apparently is not able to get the status update from "stop callback", perhaps because too busy with simulating the intensive "simulation_loop" called from "run_Callback".
> >
> > However I found a trick to give Matlab time to check stop_Callback updates.
> > The code example above works if a statement like: pause(0.000001) is placed among run_Callback instructions.
> >
> > (I found this trick in another thread, not my idea; at least in my case it works)

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us