LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

about timing loop and GUI control

Solved!
Go to solution

Hi all,

  I have a code with two buttons placed on the panel, one is RUN, another is STOP. Initially, STOP is disabled and when I kick RUN, the STOP will be disable. But when STOP is  kicked, the RUN will be activated.

 

#include "testimg.h"


#include <windows.h>
#include <utility.h>
#include "asynctmr.h"
#include <ansi_c.h>
#include <cvirte.h>		
#include <userint.h>
#include <NIDAQmx.h>
#include "toolbox.h"


static int panelHandle = 0;

static int stoprun = 0;


int main (int argc, char *argv[])
{
	int error = 0;
	
	nullChk (InitCVIRTE (0, argv, 0));
	errChk (panelHandle = LoadPanel (0, "testimg.uir", PANEL));
	
	SetCtrlAttribute(PANEL, PANEL_STOPBUTTON, ATTR_DIMMED, TRUE);
	
	errChk (DisplayPanel (panelHandle));
	errChk (RunUserInterface ());
Error:
	if (panelHandle > 0) DiscardPanel (panelHandle);
	return 0;
}


int CVICALLBACK MainPanelResponse(int panel, int event, void *callbackData, int eventData1, int eventData2)
{
  if (event == EVENT_CLOSE) QuitUserInterface (0);
  return 0;
}

int CVICALLBACK RunButtonResponse (int panel, int control, int event, void *callbackData, int eventData1, int eventData2)
{
  if (event==EVENT_COMMIT)
  {
	int N=20;
	
	stoprun = 0;
	SetCtrlAttribute(panel, PANEL_STOPBUTTON, ATTR_DIMMED, FALSE);
	SetCtrlAttribute(panel, PANEL_RUNBUTTON, ATTR_DIMMED, TRUE);
	for (int i=0; i<N; i++)
	{
	  // some heavy task
	  // here I use Sleep instead
	  Sleep(5000);
	  
	  ProcessSystemEvents();
	  Sleep(2000);
	  if (stoprun>0) break;
	}
	SetCtrlAttribute(panel, PANEL_STOPBUTTON, ATTR_DIMMED, TRUE);
	SetCtrlAttribute(panel, PANEL_RUNBUTTON, ATTR_DIMMED, FALSE);
  }
	
  return 0;
}

int CVICALLBACK StopButtonResponse (int panel, int control, int event, void *callbackData, int eventData1, int eventData2)
{
  if (event==EVENT_COMMIT)
  {
	stoprun = 1;
  }
  return 0;
}

My code is designed so to repeat a operation for N times after the START button is kicked. And if STOP button is kicked before the task is finished running. Stop the current application and return false; I wrote the code but it seems doesn't work. It seems that the application cannot be interrupted before the completete of the task. I don't know what's wrong with my code. If you have any experienence with that, could you please tell me what's wrong with my cdoe? Thanks.

0 Kudos
Message 1 of 2
(3,640 Views)
Solution
Accepted by PKIM

What you are seeing is the expected behaviour: in your loop inside the run button, you have a 5 seconds wait in which the system is frozen, next another 2 sec with the system frozen again. For simulation puroposes you should modify the code this way:

 

double tini;


tini = Timer ();
requestToStop = 0; while (Timer () - tini < 5.0 || requestToStop) { ProcessSystemEvents (); sleep (50); }

 

The Stop button then must raise a global variable that stops the loop (requestToStop in my example above).

 

In actual code, such a long lasting process should not be handled inside a control callback: you should place it elsewhere depending on how you want to structure your code so to leave the UI responsive. Available alternatives are:

 

- A UI timer callback

- An Asynchronous timer callback (similar to the preceding one but executed in a separate thread)

- A separate thread issued with CmtScheduleThreadPoolFunction

 

Whichever is the solution, the stop button must be handled inside the code by raising a signal that let the processing stop in a secure manner.



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
Message 2 of 2
(3,637 Views)