LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Cascaded counters to produce critical timing on a PCI 6601 with nidaqmx functions

I have an instrument that uses  NI PCI 6733 and PCI 6601 cards that controls a camera, an electronic shutter, current control FET and power supplies.  Control and timing was performed by traditional nidaq functions.  I have now updated to windows 7 and the latest Labwindows with NIDAQmx.  Part of the control involves cascaded timers outputing invidual pulses for control with critical timing in the microsecond range.  All of the experimental sequences were implemented with hardware timing using pulses generated by the various traditional daq counter application like FSK, triggerable, retriggerable.  Two timers on the PCI 6733 cascaded and produced timing/ control input to the four times on the 6601.

 

I can no longer implement the timing using the nidaqmx.  The same applications are missing and the nidaqmx functions do not seem to be capable of cascading the counters to that one counter can trigger a selectable pulse on another.  In fact going through all the examples I do not think that it is possible for one timer pulse to trigger another timer pulse on the 6601.  I know there are trigger functions but these apply to the whole task and if you have more than one counter then the trigger is configured for the whole task.  The retriggerable pulse example with the external trigger suffers from this problem because it requires a signal to be placed on the external terminal for it to run.

 

I am wondering why a multiple timer card is sold if cascaded hardware critical timing is not possible.  It seems simple but  the question boils down to "Can one counter pulse trigger another counter or trigger two counters for that matter?"

0 Kudos
Message 1 of 5
(4,691 Views)

Hi swrose,

 

Taking a look at the Device Routes of your devices can give you a better idea of what signals can be internally routed. Can you please let me know more specifically what you mean by cascading the counters? If possible, a timing diagram of which signals you would like to route to where would be helpful. With more information, I can try to see what options you may have using DAQmx.

 

Thanks! 

 

Julia P.
0 Kudos
Message 2 of 5
(4,661 Views)

Thank you for your interest.  I have reproduced my traditional NIDAQ timing setup below where on the 6601 the counters 1 and 3 output pulses at specific times relative to the same falling edge which was produced by paired counters 0 and 2 respectively.  Counters 0 and 2 produced identical pulse patterns and, so, probably could have been replaced by one counter.  The counters 0 and 1 on the 6733 board produce control signals to set up experiment and the pulse sequence on 6601 counters 0 and 1 (the sequence which controls the cutout for the camera operation).

 

I have been trying to duplicate this scheme but I am unable to trigger one counter with another.  I believe that I can work with my other three available counters to have solid functional timing scheme if I could get one counter to trigger a selectable pulse on the two other of the 6601 timers.  My current attempt  has been directed toward finding a vi which may show two counters 'cascaded' in this way.  I assume that the LabWindows CVI must be able to generate two or more tasks with the last task generated producing a pulse which triggers the other counters.  However I have not found any timing/ pulse examples of text based programming which show more than one task.  I have just come to this point and so have not broaded my search outside of timing.

 

Any help or direction you can give me would save me a lot of time.  I am very frustrated by my inexperience and need to quickly translate a system which I spent alot of time to get working.

 

Thanks again.

 

 

// Selecting onboard clock to be used on NI 6601
iStatus = Select_Signal(pApp->m_cTimerBoard, ND_BOARD_CLOCK, ND_BOARD_CLOCK, ND_DONT_CARE);

 

// **** Setup Blue Pulse - Counter 1 6601 Settings for Measuring pulse as retriggerable

iTime1 = (u32)(dTMeasuringPulseDelay * 20000000.0);
iTime2 = (u32)(dBluePulseTime * 20000000.0);

iStatus = GPCTR_Control(pApp->m_cTimerBoard, ND_COUNTER_1, ND_RESET);

 

iStatus = GPCTR_Set_Application(pApp->m_cTimerBoard, ND_COUNTER_1, ND_RETRIG_PULSE_GNR);

 

iStatus = GPCTR_Change_Parameter(pApp->m_cTimerBoard, ND_COUNTER_1, ND_COUNT_1, iTime1);

 

iStatus = GPCTR_Change_Parameter(pApp->m_cTimerBoard, ND_COUNTER_1, ND_COUNT_2, iTime2);

 

iStatus = GPCTR_Change_Parameter(pApp->m_cTimerBoard, ND_COUNTER_1, ND_GATE, ND_OTHER_GPCTR_OUTPUT);


iStatus = GPCTR_Change_Parameter(pApp->m_cTimerBoard, ND_COUNTER_1, ND_GATE_POLARITY, ND_HIGH_TO_LOW);

 

iStatus = Select_Signal(pApp->m_cTimerBoard, ND_PFI_32, ND_GPCTR1_OUTPUT, ND_DONT_CARE); 

 

iStatus = GPCTR_Control(pApp->m_cTimerBoard, ND_COUNTER_1, ND_PREPARE);

 

 

// **** Setup Camera Trigger - Counter 3 NI 6601
iTime1 = (u32)(dTCameraTriggerDelay * 20000000.0);
iTime2 = (u32)(dCameraTriggerPulseTime * 20000000.0);

iStatus = GPCTR_Control(pApp->m_cTimerBoard, ND_COUNTER_3, ND_RESET);

 

iStatus = GPCTR_Set_Application(pApp->m_cTimerBoard, ND_COUNTER_3, ND_RETRIG_PULSE_GNR);

 

iStatus = GPCTR_Change_Parameter(pApp->m_cTimerBoard, ND_COUNTER_3, ND_COUNT_1, iTime1);

 

iStatus = GPCTR_Change_Parameter(pApp->m_cTimerBoard, ND_COUNTER_3, ND_COUNT_2, iTime2);

 

iStatus = GPCTR_Change_Parameter(pApp->m_cTimerBoard, ND_COUNTER_3, ND_GATE, ND_OTHER_GPCTR_OUTPUT);


iStatus = GPCTR_Change_Parameter(pApp->m_cTimerBoard, ND_COUNTER_3, ND_GATE_POLARITY, ND_HIGH_TO_LOW);

 

iStatus = Select_Signal(pApp->m_cTimerBoard, ND_PFI_24, ND_GPCTR3_OUTPUT, ND_DONT_CARE);

 

iStatus = GPCTR_Control(pApp->m_cTimerBoard, ND_COUNTER_3, ND_PREPARE);

 

//*** Setup Counter 1 (6733) to trigger long pulses at either end of sequence for red actinic
iTime1 = (u32)(.001 * 20000000);
iTime2 = (u32)(.750 * 20000000);

iStatus = GPCTR_Control(pApp->m_cDABoard, ND_COUNTER_1, ND_RESET);

 

iStatus = GPCTR_Set_Application(pApp->m_cDABoard, ND_COUNTER_1, ND_PULSE_TRAIN_GNR);

 

iStatus = GPCTR_Change_Parameter(pApp->m_cDABoard, ND_COUNTER_1, ND_COUNT_1, iTime1);

 

iStatus = GPCTR_Change_Parameter(pApp->m_cDABoard, ND_COUNTER_1, ND_COUNT_2, iTime2);

 

iStatus = Select_Signal(pApp->m_cDABoard, ND_GPCTR1_OUTPUT, ND_GPCTR1_OUTPUT, ND_LOW_TO_HIGH);


iStatus = GPCTR_Control(pApp->m_cDABoard, ND_COUNTER_1, ND_PREPARE);

 

//*** Setup Counter 0 (NI6733: pApp->m_cDABoard) to generate on off pulses for Red  on 6601
iTime1 = (u32)(0.001 * 20000000.0);
iTime2 = (u32)(0.150 * 20000000.0);

iStatus = GPCTR_Control(pApp->m_cDABoard, ND_COUNTER_0, ND_RESET);

 

iStatus = GPCTR_Set_Application(pApp->m_cDABoard, ND_COUNTER_0, ND_RETRIG_PULSE_GNR);

 

iStatus = GPCTR_Change_Parameter(pApp->m_cDABoard, ND_COUNTER_0, ND_COUNT_1, iTime1);

 

iStatus = GPCTR_Change_Parameter(pApp->m_cDABoard, ND_COUNTER_0, ND_COUNT_2, iTime2);

 

iStatus = Select_Signal(pApp->m_cDABoard, ND_GPCTR0_OUTPUT, ND_GPCTR0_OUTPUT, ND_LOW_TO_HIGH);

 

iStatus = GPCTR_Change_Parameter(pApp->m_cDABoard, ND_COUNTER_0, ND_GATE, ND_OTHER_GPCTR_OUTPUT);

 

iStatus = Select_Signal(pApp->m_cDABoard, ND_RTSI_0,ND_GPCTR0_OUTPUT, ND_LOW_TO_HIGH);

 

iStatus = GPCTR_Control(pApp->m_cDABoard, ND_COUNTER_0, ND_PREPARE);

 

// Setup Red Actinic - Counter 0 - NI 6601 with two frequencies (ND_FSK applicatioin)
iTime1 = (u32)(0.005 * 20000000.0);
iTime2 = (u32)(0.050 * 20000000.0);
iTime3 = (u32)(0.001 * 20000000.0);
iTime4 = (u32)(0.150 * 20000000.0);

iStatus = GPCTR_Control(pApp->m_cTimerBoard, ND_COUNTER_0, ND_RESET);

iStatus = GPCTR_Set_Application(pApp->m_cTimerBoard, ND_COUNTER_0, ND_FSK);

iStatus = GPCTR_Change_Parameter(pApp->m_cTimerBoard, ND_COUNTER_0, ND_GATE, ND_RTSI_0);

iStatus = GPCTR_Change_Parameter(pApp->m_cTimerBoard, ND_COUNTER_0, ND_COUNT_1, iTime1);

iStatus = GPCTR_Change_Parameter(pApp->m_cTimerBoard, ND_COUNTER_0, ND_COUNT_2, iTime2);

iStatus = GPCTR_Change_Parameter(pApp->m_cTimerBoard, ND_COUNTER_0, ND_COUNT_3, iTime3);

iStatus = GPCTR_Change_Parameter(pApp->m_cTimerBoard, ND_COUNTER_0, ND_COUNT_4, iTime4);

iStatus = Select_Signal(pApp->m_cTimerBoard, ND_PFI_36, ND_GPCTR0_OUTPUT, ND_DONT_CARE);

iStatus = GPCTR_Control(pApp->m_cTimerBoard, ND_COUNTER_0, ND_PREPARE);

// Setup Blue  - Counter 2 - NI 6601 with two frequencies (ND_FSK applicatioin)
iTime1 = (u32)(0.005 * 20000000.0);
iTime2 = (u32)(0.050 * 20000000.0);
iTime3 = (u32)(0.001 * 20000000.0);
iTime4 = (u32)(0.150 * 20000000.0);

iStatus = GPCTR_Control(pApp->m_cTimerBoard, ND_COUNTER_2, ND_RESET);

 

iStatus = GPCTR_Set_Application(pApp->m_cTimerBoard, ND_COUNTER_2, ND_FSK);

 

iStatus = GPCTR_Change_Parameter(pApp->m_cTimerBoard, ND_COUNTER_2, ND_GATE, ND_RTSI_0);

 

iStatus = GPCTR_Change_Parameter(pApp->m_cTimerBoard, ND_COUNTER_2, ND_COUNT_1, iTime1);

 

iStatus = GPCTR_Change_Parameter(pApp->m_cTimerBoard, ND_COUNTER_2, ND_COUNT_2, iTime2);

 

iStatus = GPCTR_Change_Parameter(pApp->m_cTimerBoard, ND_COUNTER_2, ND_COUNT_3, iTime3);

 

iStatus = GPCTR_Change_Parameter(pApp->m_cTimerBoard, ND_COUNTER_2, ND_COUNT_4, iTime4);

 

iStatus = Select_Signal(pApp->m_cTimerBoard, ND_PFI_28, ND_GPCTR2_OUTPUT, ND_DONT_CARE);

 

iStatus = GPCTR_Control(pApp->m_cTimerBoard, ND_COUNTER_2, ND_PREPARE);

 

0 Kudos
Message 3 of 5
(4,659 Views)

Maybe I am wrong about using multiple tasks.  I am just guessing and think this outrageous that I may have broken the instrument by upgrading.  Why sell a card with multiple timers if they cannot enable each other through there gates for control purposes?

 

I hope there is someone who can help.   I cannot be the only one with this situation. Don't others use cards for instrument control?  

 

Finally, my next avenue seems to be setting the chain of triggered clocks back and forth between the cards.  Use one trigger on the 6733 to trigger two counters on the 6601.  Start the 'cascade' off on the 6601 and clear that task after it triggers the 6733.  So, the next two tasks are started on separate cards.  Seems complicated and I am not sure about connectivity issues although the routing diagrams indicate feasibility, if not doability.

0 Kudos
Message 4 of 5
(4,656 Views)

Hi swrose,

 

Looking at the Device Routes of the 6601 we can see that there are direct routes between each counters' Internal Output and the Source, Gate, and Auxiliary lines of the other couters. As such, you may be able to modify a pulse generation example to programmatically use these routes.

 

In your first post you mentioned a retriggerable pulse example with an external trigger. Can you please post this example?

 

 

Julia P.
0 Kudos
Message 5 of 5
(4,495 Views)