If you can group all control related to one instrument in a little panel, you could load it as a child on your main panel, next replicate the child panel assigning a different handle to it; those hadles can be grouped in an array of int.
This way, when a callback is triggered you can discriminate which instrument is operated on by means of the panel handle passed to the callback.
Your timer callback will look as follows:
case EVENT_TIMER_TICK:
for (i= 0; i < NUMBER_OF_SUPPLIES; i++)
{
SGA_MeasureDCVolt (instr_handle[i], &VOLTAGE_VAL[i]);
SGA_MeasureDCCurr (instr_handle[i], &CURRENT_VAL[i]);
SGA_OutputOVPQuery (instr_handle[i], &OVP_VAL[i]);
SetCtrlVal (panelHandle[i], PANEL_VOLTAGE, VOLTAGE_VAL[i]);
SetCtrlVal (panelHandle[i], PANEL_CURRENT, CURRENT_VAL[i]);
SetCtrlVal (panelHandle[i], PANEL_OVP, OVP_VAL[i]);
}
At the beginning of the application you will need to create the array and populate it with the panel handles:
int panelHandle[NUMBER_OF_SUPPLIES];
mainH = LoadPanel (0, "uirfile.uir", MAINPANEL);
panelHandle[0] = LoadPanel (mainH, "uirfile.uir", PANEL);
// Set appropriate panel position
DisplayPanel (panelHandle[0]);
for (i = 1; i < NUMBER_OF_SUPPLIES; i++) {
panelHandle[i] = DuplicatePanel (mainH, panelHandle[0], "title", top, left);
DisplayPanel (panelHandle[i]);
}
DisplayPanel (mainH);
Inside the control callbacks, discriminate the interested instrument:
int CVICALLBACK InstrCbk (int panel, int control, int event, void *callbackData, int eventData1, int eventData2)
{
int actInstr; // Instrument operated on
for (actInstr = 0; actInstr < NUMBER_OF_SUPPLIES; actInstr++) {
if (panel == panelHandle[actInstr]) break;
}
// Your code here
}
One disadvantage of this approach is that tabbing through controls does not fall into and outside child panels: your operator will need to use the mouse to change the instrument to act on.
Hope this workaround can be useful for your needs
Roberto