From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

while loop stopped by key press

Solved!
Go to solution

Hello,

I am building an applitation that in one time  in loop collects a data from multimeter and displays it on .uir panel.

I have a probelm with breaking this loop. I want to do that by pressing any key, but it does not work.
I figured out that when program is in that loop, there is no callback recognized.

 

I have tryied with GetUserEvent, but it has not worked. 

 

It could be also a solution to have a callback that generates every 0,5s and refreshes that data, but I do not know how to do that.

 

Code:

/////////////////////////////////////////////////////////

int eventPanel, eventCtrl;
QueueUserEvent (2000, panelHandleFILTER, FILTER);
do{
...


eventPanel= panelHandleFILTER;
GetUserEvent (0, &eventPanel, &eventCtrl);
}while(eventCtrl!=2000);

//////////////////////////////////////////////////

 

Best

Chris

0 Kudos
Message 1 of 9
(4,987 Views)

What do you mean by saying that GetUserEvent has not worked?

 

In the help of CVI there is an example of how to use this function, does it not work for you?

 

Basically you would use it in a loop like that:

 

cancel = FALSE;

while ( !cancel )
{
...

GetUserEvent ( 0, &event_panel, &id );
if ( id == PANEL_COMMANDBUTTON ) // your cancel button
{
    cancel = TRUE;
}

...

}

0 Kudos
Message 2 of 9
(4,981 Views)

I do that:
/////////////////////////////////////////////////////////////////

int eventPanel, eventCtrl;
do{

 

eventPanel= panelHandleFILTER;
GetUserEvent (0, &eventPanel, &eventCtrl);

}while(eventCtrl!=EVENT_KEYPRESS);

///////////////////////////////////////////////////////////////

 

whats is more, in debug view I get:
eventPanel=-1  and eventCtrl=-1
when the panelHandleFILTER=3

 

Best
Chris

0 Kudos
Message 3 of 9
(4,976 Views)

Hi Chris,

 

why don't you start with a working example and try to adapt it to your needs? That's usually more efficient than starting from scratch... Smiley Wink

 

Either take one of the code snippets from the help file or open one of the examples provided with CVI. I would suggest the example projects getuserevent.cws, callback.cws, and timer.cws

 

Concerning your code please note that the third parameter of GetUserEvent is a control id (or a menu item id) and not an event.

From the help: Returns the ID of the control or menu item on which the commit event occurred.
Also note that it states commit event (not keypress event or left click event...): GetUserEvent reacts to this event only.

 

Also note that panel ids and control ids should not be negative, if they are, an error occurred. How do you load your panel, i.e., where do you get your panelHandleFILTER from? Did you check for the return value of LoadPanel - this code you didn't show...

0 Kudos
Message 4 of 9
(4,973 Views)

You  are right.
I have added a button to break a loop and it works.
Pressing the button stops the loop.
The difficulty is that in my project prescribtion I need to stop that reading procedure by any key pressed. 
I have asked them and they do not want to stop that by pressing a button. Only any key pressed.

Maybe you now how to make a callback that will execute a code every 1s, that in the time between this callback appears program could read a press key callback.

Simply I want to change while loop into  something like timer overflow interrupt (like on uC).

 

About LoadPanel function it works fine. 
All Panels shows on screen.

 

Best
Chris.

0 Kudos
Message 5 of 9
(4,952 Views)

@BiedaK wrote:
I figured out that when program is in that loop, there is no callback recognized.

 


So may be the following will help:

- Add ProcessSystemEvents () to your loop

- Install a panel callback where you check for and react to EVENT_KEYPRESS

 

0 Kudos
Message 6 of 9
(4,949 Views)

I think you should add a new thread in your program, start it at the beginning, and wait for the Keypress you need. In the new thread you'll have something like :

 

 

switch ( event)

{

      EVENT_KEYPRESS :

          switch (eventData1)

          {

               case YOUR_EVENT :

                    // Stop your program

               break;

          }

     break;

}

 

                    

 

 

0 Kudos
Message 7 of 9
(4,945 Views)
Solution
Accepted by topic author BiedaK

Well, that's a different philosophy Smiley Wink : If one is new to CVI I wouldn't start with the more complicated issues such as multi-threading, although it may be more elegant, more cpu efficient etc.

 

The following code works; it will not win a price but can be implemented in two minutes (or less, depending on typing speed Smiley Very Happy). It can also be easily adapted to use a timer for data acquisition, as shown in the example timer I have suggested to look at earlier.

 


 

#include <cvirte.h>        
#include <userint.h>
#include "keypress.h"

static int data = 1;
static int panelHandle;

int main (int argc, char *argv[])
{
    if (InitCVIRTE (0, argv, 0) == 0)
        return -1;    /* out of memory */
    if ((panelHandle = LoadPanel (0, "keypress.uir", PANEL)) < 0)
        return -1;
    DisplayPanel (panelHandle);
    RunUserInterface ();
    DiscardPanel (panelHandle);
    return 0;
}

int CVICALLBACK PanelEvents (int panel, int event, void *callbackData,
        int eventData1, int eventData2)
{
    switch (event)
    {
        case EVENT_KEYPRESS:
            data = 0;
            SetCtrlVal ( panel, PANEL_LED, 0 );
            break;
    }
    return 0;
}

int CVICALLBACK Start (int panel, int control, int event,
        void *callbackData, int eventData1, int eventData2)
{
    switch (event)
    {
        case EVENT_COMMIT:
            data = 1;

            SetCtrlVal ( panel, PANEL_LED, 1 );
            while ( data )
            {
               ; // take data
               ProcessSystemEvents ();
            }
            break;
    }
    return 0;
}

int CVICALLBACK Quit (int panel, int control, int event,
        void *callbackData, int eventData1, int eventData2)
{
    switch (event)
    {
        case EVENT_COMMIT:
            QuitUserInterface ( 0 );
            break;
    }
    return 0;
}

Message 8 of 9
(4,941 Views)

ProcessSystemEvents ();    WON!!!

 

Thank you very much, it works!

I read also about multithreading in CVI, and that is good knowledge to use later in more advanced ones. 
I have a simple step-by-step tesing procedures.

 

 

Best regards,
Chris

0 Kudos
Message 9 of 9
(4,933 Views)