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! 😉