LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

I need to get the value I return in my call back methods, so that it can be formed into equations in my main?

In the following code I have call back methods that are supposed to return its output values. In my main I am writing equations from the values returned from these call backs. My question is how to call in the value from the call backs into my main. each callbacks have lots of parameters and I am sure what values to put in when I call in the callback methods. Do I use the methodname(param, param1, param2) ? But that just call in the whole method, I just want the value I am returning. Thank You.

 

Following is my code. I have also attached it.

 

#include <gpib.h>
#include <ansi_c.h>
#include <cvirte.h>    
#include <userint.h>
#include "toolbox.h"
#include "RAMP_DAC.h"


static int panel;
static int gpibdevice;
int main (int argc, char *argv[])  {
 int error = 0;
    int steps;
 int time;
    /* initialize and load resources */
    nullChk (InitCVIRTE (0, argv, 0));
    errChk (panel= LoadPanel (0, "RAMP_DAC.uir", PANEL));
   
    /* display the panel and run the user interface */
    errChk (DisplayPanel (panel));
    errChk (RunUserInterface ());
 
    steps= (setout.Set_toCB()-InitialCB(initialout))/(Voltage_stepCB(vsout));
 time= ((1000)*(Voltage_stepCB(vsout)))/(ramp_rateCB(rampout));
Error:
    /* clean up */
    DiscardPanel (panelHandle);
    return 0;
}
 
 }

int CVICALLBACK ChannelCB (int panel, int control, int event,
  void *callbackData, int eventData1, int eventData2)
{   
 //gpibdevice= ibdev(0, 12, 0, 13, 1, 0);
 
    int channel;
 switch (event)
 {
  case EVENT_COMMIT:
  
  
  GetCtrlVal (panel, PANEL_Channel, &channel);
  break;
 }
 return (channel);
}

int CVICALLBACK Set_toCB (int panel, int control, int event,
  void *callbackData, int eventData1, int eventData2)
{
 //gpibdevice= ibdev(0, 12, 0, 13, 1, 0);
 
    int setout;  
 switch (event)
 {
  case EVENT_COMMIT:
  
  
  GetCtrlVal (panel, PANEL_Set_to, &setout);
  break;
 }
 return (setout);
}

int CVICALLBACK ramp_rateCB (int panel, int control, int event,
  void *callbackData, int eventData1, int eventData2)
{
 int rampout;
 switch (event)
 {
  case EVENT_COMMIT:
   
    
   GetCtrlVal (panel,  PANEL_ramp_rate, &rampout);
   break;
 }
 return (rampout);
}

int CVICALLBACK Voltage_stepCB (int panel, int control, int event,
  void *callbackData, int eventData1, int eventData2)

{
 int vsout; 
 switch (event)
 {
  case EVENT_COMMIT:
  
   
  GetCtrlVal(panel, PANEL_Voltage_step , &vsout);
  break;
 }
 return (vsout);
}

int CVICALLBACK InitialCB (int panel, int control, int event,
  void *callbackData, int eventData1, int eventData2)
{
 int initialout;
 switch (event)
 {
  case EVENT_COMMIT:
   
   
   GetCtrlVal (panel,  PANEL_Initial, &initialout);
   break;
 }
 return (initialout);
}

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

   break;
 }
 return 0;
}

0 Kudos
Message 1 of 6
(4,252 Views)

Hi LWnovice, it seems that you are missing some very basic concept about CVI callback mechanism.

 

You main () looks quite right: you are loading a panel and displaying it and next you call RunUserInterface () to start handling user events. What you are missing here is the idea that the code past RunUserInterface is executed only after a call to QuitUserInterface () is issued. That is to say, you are never handling your equation until the user presses "Quit" button!

 

While a CVI program is under execution if effectively stays in RunUserInterface, unless some event is generated for example in a control callback: in that moment, the corresponding code in the callback function is executed; when it is terminated, the program returns to rest in RunUserInterface waiting for further events.

 

Third idea, every callback has its own variable space, which is lost after callback execution. Control values retrieved inside a callback are therefore valid only within the callback life, unless you save them in variables with module or global scope.

 

Now, I have not seen your user interface, but I suppose you have set a callback for every numeric or other type of control: it seems to me that you should organize it in slightly different way: get rid of all callbacks; place a "Execute" button on your panel; set a callback only for that button; inside the callback handle EVENT_COMMIT event in which you retrieve the values of all controls and elaborate your equation.

 

(And do not continue to try calling "methods" in a C++-like way: CVI has nothing to do with it!) Smiley Wink



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 6
(4,245 Views)

Is this more like what you were saying? I have attached the .c and .uir files for a yes or a no? But still when I set a value at each of the buttons in my .uir file I still doesn't actually communicate the values into the equations? I dont understand how setting up th equations in the single callback can give me the desired results as to I still need to call my callback in my main in order to run what I am assigning the callback to do. But this goes back to my original questions as to how to call in my callback from the main since there are many params for the callbacks and I am not sure what values goes into what params.

Thank You for your reply,

 

Download All
0 Kudos
Message 3 of 6
(4,205 Views)

As far as I can see the structure is now what I suggested you. You could put a breakpoint inside the control callback ExecuteCB () and see what happens: the callback will be executed every time you press 'Execute' button. I suggest you a few minor additions:

 

  • Set boundaries for numeric controls: at present, all controls can have every possible value depending on the data type. By setting approproate limits to each of them you can assure that the user cannot input incorrect values (as an example, it is advisable that the voltage set point can assume only values from 0 to the maximum your instrument can output). By setting 'Range checking' to 'coerce' the system will automatically limit user input; while setting it to 'validate' your program can be warned in case a control is out-of-range by calling ValidatePanel()
  • Add additional check to validate control values in case some of them is incoherent with respect to another (e.g. the ramp step can only be slow for high level voltage output or so)

 

I don't know what you are trying to do with the code, but at least in this moment you have all values read from the panel and ready to handle. In particular, the highlighted while loop has no way to terminate, but I suppose you have to add someting inside it after calculating 'steps'.

 

    switch (event) {
        case EVENT_COMMIT:
            GetCtrlVal (panel, PANEL_Channel, &channel);  
            GetCtrlVal (panel,  PANEL_ramp_rate, &rampout);  
            GetCtrlVal (panel, PANEL_Set_to, &setout);
            GetCtrlVal (panel, PANEL_Voltage_step , &vsout);
            GetCtrlVal (panel,  PANEL_Initial, &initialout);
            GetCtrlVal (panel,  PANEL_Execute, &executeout);

            time = (1000 * vsout) / (rampout);
            while (initialout <= setout) {
                steps = (setout - initialout) / (abs(vsout));
            }
             break;
    }



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?
0 Kudos
Message 4 of 6
(4,181 Views)

Thank you for the reply. This program is basically to increase/decrease the DAC channel 1,2,3 or 4's voltage output by untilizing what value the user inputs in the .uir file for the setto(final) voltage, the ramp_rate which is (millivolts/sec) and the voltage step which is just millivolts. The initial voltage is always zero and the user can/should be able to input a negative volts for the setto so that the DAC channels voltage out can increase in the negative direction. The steps and the time I calculated out is basically equations which define at what specific time interval, how many steps need to be taken in order to reach the setto voltage. I suppose from reading your reply I am far from achiveing the code I want. Am I going about it completely wrong or just need more loops. I was thinking I may need a for loop insetead of a while loop for the staments. Please let me know if possible. And also ValidatePanel() needs to called from the main?

Sincerely,

0 Kudos
Message 5 of 6
(4,154 Views)

You can call ValidatePanel as the first line inside the button callback: only if the function returns ok you can go on retrieving control values and so on.

 

Regarding the loop, both using a while or a for can lead to success but you must be sure that the loop comes to an end. You will need then to add DAQ instructions to drive voltage output.

 

Remember that while in the loop/for you are not handling user events: during the voltage ramp you will be not even able to stop it if you want to. This situation need a ProcessSystemEvents () inside the loop/for so that user events can be handled. A Stop button callback could for example raise a flag in a global variables that is monitored inside the loop.

This approach will indeed work, nevertheless, this is not the best scenario you can imagine: a better way could be to use a timer to execute the voltage ramp at the desired pace, leaving the system responsive to user action.



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?
0 Kudos
Message 6 of 6
(4,146 Views)