05-29-2014 09:15 AM
Hello,
I am trying to develop a vision application with CVI that loads files. vbai after connection...the application interface has two positions (left and right)...I want the two buttons START calls the same function CVICALLBACK ( Inspection)....and this function call the function ThreadFunction and its parameter is thread (thread number)...
I said two tables Elements to control the two threads and I worked on these tables in the processing function ThreadFunction...
Now I have not grasped how I pass the thread number for CVICALLBACK inspection function, in fact, when I click on START on the left position inspection starts left, right when it starts to right, Also, if I click on the two positions she embarked on two positions ...
Thank you for your help, it is urgent
#include <utility.h>
#include <ansi_c.h>
#include <cvirte.h>
#include <userint.h>
#include <cvi2009compat.h>
#include "toolbox.h"
#include "nivision.h"
#include "VBAIInterfaceC.h"
#include "ann.h"
static int panelHandle;
static CmtTLVHandle tlvHandle = 0;
static volatile int exiting = 0;
static int Tab_serial_num[2]={PANEL_SERIAL_NUM,PANEL_SERIAL_NUM2};
static int Tab_inspec_name[2]={PANEL_INSPECTION_NAME,PANEL_INSPECTION_NAME2};
static int Tab_inspec_butt[2]={PANEL_INSPECT_BUTTON,PANEL_INSPECT_BUTTON2};
static int Tab_ecr_acc_stat[2]={PANEL_ECR_ACC_STAT,PANEL_ECR_ACC_STAT2};
static int Tab_led_metro_stat[2]={PANEL_LED_METRO_STAT,PANEL_LED_METRO_STAT2};
static int Tab_led_vert_stat[2]={PANEL_LED_CPL_VERT_STAT,PANEL_LED_CPL_VERT_STAT2};
static int Tab_led_rouge_stat[2]={PANEL_LED_CPL_ROUGE_STAT,PANEL_LED_CPL_ROUGE_STAT2};
static int Tab_led_jaune_stat[2]={PANEL_LED_CPL_JAUNE_STAT,PANEL_LED_CPL_JAUNE_STAT2};
static int Tab_lcd_off_stat[2]={PANEL_LCD_OFF_STAT,PANEL_LCD_OFF_STAT2};
static int Tab_lcd_on_stat[2]={PANEL_LCD_ON_STAT,PANEL_LCD_ON_STAT2};
static int Tab_main_window[2]={PANEL_MAIN_WINDOW,PANEL_MAIN_WINDOW2};
static int Tab_test_stat[2]={PANEL_TEST_STATUS,PANEL_TEST_STATUS2};
static int Tab_text_error[2]={PANEL_ERROR_TEXT,PANEL_ERROR_TEXT2};
void DisplayError(VBAIError error);
void ButtonStatDisplay(void);
void IndicatorStat(int ind, bool32 stat ) ;
static int CVICALLBACK ThreadFunction (int thread) ;
/*static int SetupApplication (void);
static int ShutdownApplication (void);*/
int main (int argc, char *argv[])
{
if (InitCVIRTE (0, argv, 0) == 0)
return -1; /* out of memory */
if ((panelHandle = LoadPanel (0, "ann.uir", PANEL)) < 0)
return -1;
...;
...;
DisplayPanel (panelHandle);
RunUserInterface ();
DiscardPanel (panelHandle);
if (stepResults != NULL)
free (stepResults);
vbaiCloseConnection (session, 1) ;
return 0;
}
void DisplayError(VBAIError error)
{
...;
void IndicatorStat(int ind, bool32 stat )
{
...;
}
int CVICALLBACK INSPECTION (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
VBAIError error = VBAIErrorSuccess;
switch (event)
{
case EVENT_COMMIT:
!!!!!!!!! The problem !!!!!!!!!!
break;
}
if (error)
DisplayError(error);
return 0;
}
static int CVICALLBACK ThreadFunction (int thread)
{
....;
while(!exiting){
SetCtrlAttribute(panelHandle,Tab_inspec_name[thread],ATTR_DIMMED,0);
;
switch(i) {
case 0: IndicatorStat(Tab_ecr_acc_stat[thread],inspectionStatus);
break;
case 1: IndicatorStat(Tab_led_metro_stat[thread],inspectionStatus);
break;
case 2: IndicatorStat(Tab_led_vert_stat[thread],inspectionStatus);
break;
case 3: IndicatorStat(Tab_led_rouge_stat[thread],inspectionStatus);
break;
;
case 4: IndicatorStat(Tab_led_jaune_stat[thread],inspectionStatus);
break;
case 5:IndicatorStat(Tab_lcd_off_stat[thread],inspectionStatus);
break;
case 6: IndicatorStat(Tab_lcd_on_stat[thread],inspectionStatus);
break;
}
Delay(0.5);
...;
...;
...;
Solved! Go to Solution.
05-30-2014 02:56 AM
Hi schweini,
Your thread function prototype does not look correct.
Its input should be a void pointer, not integer.
To pass to your thread which button started it, you can use that parameter.
But you have to pass a pointer to a valid variable.
In your thread you are going to get the value by dereferencing the data pointer.
Here is some sample (pseudo)code.
See if it makes sense.
//in your Start callback
static int start; //static is crucial here
switch (event)
{
case EVENT_COMMIT:
start = (control == PANEL_START_1 ? 1 : 2);
CmtScheduleThreadPoolFunction (pool, ThreadFunction, &start, &funcId);
break;
}
//in your thread function
int CVICALLBACK ThreadFunction (void *data)
{
int which_side;
which_side = *((int*)data);
while (!exiting)
{
if (which_side == 1)
{..}
else
{..}
}
}
05-30-2014 09:06 AM - edited 05-30-2014 09:19 AM
Thank you ebalci ,
First of all, what indicate the variable Which Side? Remember that the treatment is the same for both START buttons, so I want when I click on the two buttons the program works in parallel ...
labels for the controls to the left position : {PANEL_INSPECTION_NAME,PANEL_INSPECT_BUTTON,PANEL_ECR_ACC_STAT,PANEL_LED_METRO_STAT,...,PANEL_MAIN_WINDOW,...}
labels for the controls to the right position : {PANEL_INSPECTION_NAME2,PANEL_INSPECT_BUTTON2,PANEL_ECR_ACC_STAT2,PANEL_LED_METRO_STAT2,...,PANEL_MAIN_WINDOW2,....}
The pseudocode of treatement for my ThreadFunction :
while(!exiting)
{ SetCtrlAttribute(panelHandle,PANEL_INSPECTION_NAME,ATTR_DIMMED,0); //when PANEL_INSPECT_BUTTON has clicked
// SetCtrlAttribute(panelHandle,PANEL_INSPECTION_NAME2,ATTR_DIMMED,0); when PANEL_INSPECT_BUTTON2 has clicked
do{ i++; error = vbaiOpenInspection (session, path[i]);
if (error == VBAIErrorSuccess)
{ if (stepResults != NULL) { ...; }
error = vbaiGetInspectionInfo (session, &info);
if (error) break;
SetCtrlAttribute (panelHandle,PANEL_INSPECTION_NAME, ATTR_CTRL_VAL, info.productName);
//SetCtrlAttribute (panelHandle,PANEL_INSPECTION_NAME2, ATTR_CTRL_VAL, info.productName);When second position (right)
error = vbaiRunInspectionOnce (session, -1);
if(error) break;
if (stepResults == NULL) { ...; } ...;
switch(i)
{ case 0:
IndicatorStat(PANEL_ECR_ACC_STAT,inspectionStatus); break; //when position left
//IndicatorStat(PANEL_ECR_ACC_STAT2,inspectionStatus); break; when position right
case 1:
IndicatorStat(PANEL_LED_METRO_STAT,inspectionStatus);break;//when position left
// IndicatorStat(PANEL_LED_METRO_STAT2,inspectionStatus);break;when position right
case 2: ...; case 3: ...; case 4: ...; ...; case 6: ...;
}
//load a image file for my disk (image inspection )
Delay(0.5);
DisplayImageFile(panelHandle,PANEL_MAIN_WINDOW,file); //when position left
// DisplayImageFile(panelHandle,PANEL_MAIN_WINDOW2,file);when position right
}
}
...; }
06-01-2014 04:29 PM
Please help me, it is urgent
06-01-2014 10:58 PM - edited 06-01-2014 11:00 PM
Hi,
Which_side veriable tells you which start button is pressed.
I see you have arrays for the user interface controls.
So you do not need the if/else blocks I wrote.
You can use which_side variable as an index.
First change the code line in callback as follows:
start = (control == PANEL_INSPECT_BUTTON ? 0 : 1);
Then change your inspection code such that you use the arrays instead of each control id.
Just replace which_side instead of your the variable you named "thread"
06-02-2014 05:25 AM - edited 06-02-2014 05:26 AM
Thank you very much Ebalci, the program works perfectly ![]()
06-02-2014 07:04 AM - edited 06-02-2014 07:05 AM
I am glad it worked for you.
Why not give some "kudos" if it saved the day! 😉