LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Listbox setctrlindex blue focus

Hi,
I am using a listbox, and the function setctrlindex to move the index in the listbox in order to send the values at the actual control index sequently to a motor,
but I don't know if the blue focus which usually hilight the focused raw but when I put my sequence in a loop the blue highlightning focus doesn't show up during the run.
Why is that? is there a way to make it appear?
plus I have a button to stop the sequence and it attribute is dimmed normally and I want it to be activate during the while loop run, so here is my code could you explain me why the button is still dimmed during loop run, and how to make it work?

int CVICALLBACK Start_Sequence_Button_CB (int panel, int control, int event,
        void *callbackData, int eventData1, int eventData2)
{
    void *actual_speed_command=0;
    int ItemPosition=0;
    ListType LISTBOX=0;
    int i=0,j=0;
    double t0=0;
    double t1=0;
    int Number_of_cycles=0;
    int durationstrlenght=0;
    int speedstrlenght=0;
    double x=0;


    switch (event)
    {
        SetCtrlAttribute(dvdxt, DVDXT_LISTBOX, ATTR_DIMMED, 1);
        SetCtrlAttribute(dvdxt, DVDXT_Stop_Sequence_Button, ATTR_DIMMED, 0);
        SetCtrlAttribute(dvdxt, DVDXT_Start_Sequence_Button, ATTR_DIMMED, 1);
       
       
        case EVENT_COMMIT:
 
           
            GetCtrlVal(dvdxt, DVDXT_Cycle_Number, &Number_of_cycles);
           
            if(Listsize!=0)
            {
               
                for(j=0;j<Number_of_cycles+1;j++)
                {
                    SetCtrlVal(dvdxt, DVDXT_Actual_Cycle, j);
                    SetCtrlIndex(dvdxt, DVDXT_LISTBOX, 0);
                 
                    while((ItemPosition != Listsize)&&(stop == 0))
                    {
                        ListGetItem(LISTBOX, actual_speed_command, ItemPosition);
                       
                        t0 = Timer();

                        if(ItemPosition < Listsize)
                            {
                                SetCtrlIndex(dvdxt, DVDXT_LISTBOX, ItemPosition);
                               
                                GetLabelFromIndex (dvdxt, DVDXT_LISTBOX ,ItemPosition , &Speedurationstring[i]);
                           
                                durationstrlenght=strlen(duration);
                                speedstrlenght=strlen(speed);
                               
                                ConvertArrayType(duration, VAL_CHAR,duration, VAL_DOUBLE, durationstrlenght);
                                ConvertArrayType(speed, VAL_CHAR,speed, VAL_DOUBLE, speedstrlenght);
                               
                                i++;
                                ItemPosition++;
                               
                                SetCtrlAttribute(dvdxt, DVDXT_LISTBOX, ATTR_DIMMED, 0);
                                   SetCtrlAttribute(dvdxt, DVDXT_Stop_Sequence_Button, ATTR_DIMMED, 1);
                                SetCtrlAttribute(dvdxt, DVDXT_Start_Sequence_Button, ATTR_DIMMED, 0);
                               
                                SyncWait (t0, 3);
                                   
                            }
                            else
                            {
                                SetCtrlIndex(dvdxt, DVDXT_LISTBOX, 0);
                               
                            }
                               
                    }
                    SetCtrlVal(dvdxt, DVDXT_Actual_Cycle, 0);
                          
                }

            }
         
            break;
    }
    return 0;
}


moreover I d like Daqmx acquistion to continue during the sequence, and it actually stops, how should I make it ?

Thanks by advance
Olivier


0 Kudos
Message 1 of 18
(4,652 Views)
The blue highlighting bar only shows when the listbox it the active control, otherwise you should see a dotted box around the active element in the list.
 
Regarding daqmx and your loop, where is the acquisition task defined? I see no daq code in your function so it's not possible to try answering your question...
 
In my opinion you could simplify your code for example moving dimming instruction for your start and stop button outside the for loop, since they are always repeated with the same values. Also the code between the switch statement and the first CASE is a little strange and shoud be arranged in some other way: in your actual code you are dimming the start button every time you execute its callback (even for got focus or lost focus event, for example!) then in the commit case you reactivate it again... seems a little bit odd to me... Try figuring which is the exact desired state of the buttons in every confition and adapt your code to follow these lines.


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 2 of 18
(4,643 Views)
I didn't focused yesterday on the Syncwait included in your callback!
How long is expected to last your callback? Keep in mind that is not a good practice to have a very long lasting callback since it can affect all the callback mechanism and introduce a serious handicap on the possibility that the system can behave coherently.
In case of long lasting events, the usual suggestion is to move the code outside control callbacks, either putting it in a separate thread or at least in a timer control that fires periodically, structuring the code in small chunks (for example with the state machine paradigm)


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 3 of 18
(4,637 Views)
Hi,
Actually the syncwait is here because I d like tthe step duration to be define by the duration value in the listbox item, but my problem is that the listbox is a string value and I must convert the string into a double value speed which will be send to the engine when my application will be done, and the duration valur has to be converted as an integer to be use in the timer function.
I am actually using the format function but the result of the conversion is always zero and I don't understand why.

Thank you

Olivier





0 Kudos
Message 4 of 18
(4,631 Views)
You can scan the string to detect the value included in it using for example:
  GetLabelFromIndex (dvdxt, DVDXT_LISTBOX ,ItemPosition , &Speedurationstring[i]);
  sscanf (Speedurationstring[i], "%f", &value);
 
The lenght of each step could be associated to the list element in the listbox and retrieved with GetValueFromIndex


Message Edited by Roberto Bozzolo on 01-25-2008 02:32 PM


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 5 of 18
(4,632 Views)
Hi again,
about the daqmx acquisition here is how I did it ,


int main (int argc, char *argv[])
    {
    TaskHandle SpeedTorqueTask;
    TaskHandle SpeedTask;
    TaskHandle TorqueTask;
    char DataBuffer[1024]="0";
    int i=0;
   


    if (InitCVIRTE (0, argv, 0) == 0)
        return -1;    /* out of memory */
    if ((dvdxt = LoadPanel (0, "DVDXT IHM.uir", DVDXT)) < 0)
        return -1;
    DisplayPanel (dvdxt);
   
    /*Demande a l'utilisateur de choisir un chemin pour l'enregistrement des donnees, si l'utilisateur annule cela aura pour effet d'arreter l'application*/
   
    if (FileSelectPopup ("c:\\", "*.txt", "*.txt", "Choose FilePath for data storage", VAL_LOAD_BUTTON, 0, 0, 1, 1, File_Path)
    != VAL_EXISTING_FILE_SELECTED);
   
    else SetCtrlAttribute(dvdxt, DVDXT_File_Browser_Path, ATTR_CTRL_VAL, File_Path);
               
    SetCtrlAttribute(dvdxt, DVDXT_LISTBOX, ATTR_DIMMED, 0);
    SetCtrlAttribute(dvdxt, DVDXT_Stop_Sequence_Button, ATTR_DIMMED, 1);
    SetCtrlAttribute(dvdxt, DVDXT_Start_Sequence_Button, ATTR_DIMMED, 0);
   
   
    /*Start, and configure DAQ Acquisition*/      
   

    DAQmxLoadTask("Speed Torque Acquisition 721", &SpeedTorqueTask);
   
    GetCtrlVal(dvdxt, DVDXT_File_Browser_Path, DataFilePath);
   
    OpenFile(File_Path, VAL_WRITE_ONLY, VAL_APPEND, VAL_ASCII);
   
    SetCtrlAttribute(dvdxt, DVDXT_SpeedTorqGraph, ATTR_DATA_MODE, VAL_DISCARD);
   

           
   
   
    while(Quit==0)
        {
            DAQmxSetReadAttribute(SpeedTorqueTask, DAQmx_Read_ChannelsToRead,"Speed Acquisition 721","Torque Acquisition 721");
           
            DAQmxSetBufferAttribute(SpeedTorqueTask, DAQmx_Buf_Input_BufSize, 1024);
           
            DAQmxStartTask(SpeedTorqueTask);
           
            DAQmxReadAnalogF64(SpeedTorqueTask, 1024, 10,DAQmx_Val_GroupByChannel, SpeedTorqueArray,2048, &samplesPerChan,NULL);
           
            ArrayToFile (File_Path, SpeedTorqueArray, VAL_DOUBLE, 2048, 2,VAL_DATA_MULTIPLEXED, VAL_GROUPS_AS_COLUMNS,VAL_SEP_BY_TAB, 10, VAL_ASCII,VAL_APPEND);
           
            Decimate (SpeedTorqueArray, 2048, 2, 0, SpeedArray);
           
            SetCtrlVal(dvdxt, DVDXT_Speed_indicator, SpeedArray[512]);
           
            SetCtrlVal(dvdxt, DVDXT_Torque_indicator, TorqueArray[512]);
           
            SetCtrlAttribute(dvdxt, DVDXT_SpeedTorqGraph, ATTR_ACTIVE_YAXIS, VAL_LEFT_YAXIS); 
           
            PlotY(dvdxt, DVDXT_SpeedTorqGraph,SpeedArray,1024, VAL_DOUBLE, VAL_THIN_LINE, VAL_EMPTY_SQUARE, VAL_SOLID, 1, VAL_RED);
           
            SetCtrlAttribute(dvdxt, DVDXT_SpeedTorqGraph, ATTR_ACTIVE_YAXIS, VAL_RIGHT_YAXIS);
           
            Decimate (SpeedTorqueArray + 1, 2047, 2, 0, TorqueArray);
           
            PlotY(dvdxt, DVDXT_SpeedTorqGraph,TorqueArray,1024, VAL_DOUBLE, VAL_THIN_LINE, VAL_EMPTY_SQUARE, VAL_SOLID, 1, VAL_BLUE);
           
            DAQmxStopTask(SpeedTorqueTask);
                             
            ProcessSystemEvents();

        }
   
   
   
    RunUserInterface ();

    DiscardPanel (dvdxt);
    return 0;
    }

and the listbox function is in another callback.
0 Kudos
Message 6 of 18
(4,636 Views)

It's quite clear now why your acquisition is stopped while you are running the start button callback: you are not allowing inside your loop the execution of other parts of the code (like on the contrary you are allowing inside the loop in the main function by using ProcessSystemEvents  function).

Given this, I personally discourage you from having two concurrent loops each of them with a ProcessSystemEvents inside: this could lead to a totally unpredictable behaviour of your system. I suggest you instead to modify your application structure in such a way that:

1. You have a DAQmx task that continuously acquires measures from the field and periodically fires a callback by using DAQmxRegisterEveryNSamplesEvent. Inside that callback you can read your measures and accumulate them on disk avoiding the overhead of starting and stopping the task at each iteration. The task need to be stopped when the program exits (or upon user request or in some other way during your program life)

2. After launching your task you issue the ProcessSystemEvents that starts all user interface events handling

3. You have a start button that simply starts a new thread and exits immediately. In the separate thread you can handle your test procedures. Alternatively, the start button can enable a timer control (or an asyncronous timer) if you can structure your loop in a way that can be handled with a timer, a state machine or something similar.

Item 1 could be embedded into the callback in item 3 if your acquisition need to be active only while the test is running and not during all program life.



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 7 of 18
(4,641 Views)
Hi,
Firstable I don't understand why my duration values always return the last duration value in the lisbox after using   sscanf (Speedurationstring[i], "%f", &value);.
I cant add my code in this window because message is limited to 10000 chars. so I join my main file.

Not too much change but the only duration value I get after adding    sscanf (Speedurationstring[i], "%f", &value); is the duration value of the last item in the listbox

moreover I don't really get what you said about organizing my code differently:
what is supposed to be the "X" parameter in this function DAQmxRegisterEveryNSamplesEvent(SpeedTorqueTask, DAQmx_Val_Acquired_Into_Buffer, 1024, 0, "X",0); I guess this function is able to switch daq task to the callback desired callback function but should I put the name pf my callback at the X parameter?
the processystemevents function must be runned at the and of daq part or just after hte launch of the task?

3. You have a start button that simply starts a new thread and exits immediately. In the separate thread you can handle your test procedures. Alternatively, the start button can enable a timer control (or an asyncronous timer) if you can structure your loop in a way that can be handled with a timer, a state machine or something similar.

about that point which start button are you talking about and, I don't really know how to use timed loop ( as I said I am a CVI nwebie, basically more a labview user)

I am sorry to ask you that, but could you give me an exemple of what you were meanning about switching between daq and userinterface tasks

Thank you so much, you are really helpfull

Olivier
0 Kudos
Message 8 of 18
(4,633 Views)
I made up a simple project that acquires measures on a daq device while handling a simple test sequence: take a look at it and see if it explains a little better the structure I was suggesting you before.


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 9 of 18
(4,610 Views)
Hi roberto
I have modified my code according to you advice but I still receive an error when running the acquisition.
 NON-FATAL RUN-TIME ERROR:   "DVDXTmain.c", line 355, col 5, thread id 0x00000FB0:   Function DAQmxReadAnalogF64: (return value == -200279 [0xfffcf1a9]). Attempted to read samples that are no longer available. The requested sample was previously available, but has since been overwritten.  Increasing the buffer size, reading the data more frequently, or specifying a fixed number of samples to read instead of reading all available samples might correct the problem. Property: DAQmx_Read_RelativeTo Corresponding Value: DAQmx_Val_CurrReadPos  Property: DAQmx_Read_Offset Corresponding Value:    Task Name: Speed Torque Acquisition 721  Status Code: -200279
I guess I have to modify the acquisition parameters.
I attached my modified code.

Thanks
Olivier

0 Kudos
Message 10 of 18
(4,571 Views)