Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

trigger event

Solved!
Go to solution

Dear NI Experts:

I use NI-DAQmx ANSI C to develop software to acquire analog signal by PCIe-6351.  The sample clock is generated internally, which will be output to trigger a transducer. The sample clock's rate is about 4HZ. I will acuqire finite amouts of data on each digital trigger, which is  retriggerable. The snippet of code like this:

    DAQmxCreateTask("",&taskHandle);
    DAQmxCreateAIVoltageChan(taskHandle,"Dev1/ai0","",DAQmx_Val_Cfg_Default,-10.0,10.0,DAQmx_Val_Volts,NULL);
    DAQmxCfgSampClkTiming(taskHandle,"",10000.0,DAQmx_Val_Rising,DAQmx_Val_FiniteSamps,1000);
    DAQmxCfgDigEdgeStartTrig(taskHandle,"/Dev1/PFI0",DAQmx_Val_Rising);
    DAQmxSetStartTrigRetriggerable(taskHandle,1);    

    DAQmxRegisterEveryNSamplesEvent(taskHandle,DAQmx_Val_Acquired_Into_Buffer,1000,0,EveryNCallback,NULL);

However I need to record data from RS232 at every trigger starts exactly which need to synchronize with the analog signal record.

So My question is how can I get every start trigger event or call back. If not, then how can I read the timestamp of every start trigger?

Thanks very much.

0 Kudos
Message 1 of 7
(4,141 Views)

In the NI-DAQmx C Reference Help file (linked below), I found the following function that might be of interest to you:

"DAQmxRegisterSignalEvent"

 You could configure your device to output the start trigger and then read it back in on a Digital Input line and configure the DI Change Detection.  

 

The following manual can help you set that up:

http://www.ni.com/pdf/manuals/370784d.pdf

 

http://digital.ni.com/manuals.nsf/websearch/6A79EF4F9F30AFC086257A4400600861

 

-Nathan

Systems Engineer
SISU
0 Kudos
Message 2 of 7
(4,119 Views)

Dear Nathan:

 Thanks for your replay.

 

  Do you mean that I output the trigger pulse and intput it back to the DI line by cable?

 

   I gernerate the counter like this:

    DAQmxErrChk (DAQmxCreateCOPulseChanFreq(taskHandle,"Dev1/ctr0","",
                                            DAQmx_Val_Hz, //units
                                            DAQmx_Val_Low, //idleState
                                            2.0,   //initialDelay
                                            4,     //freq
                                            0.2)); //dutyCycle

 

 

  Can I route the counter pulse to the DI port/line internally? Like this:

  

   DAQmxConnectTerms("Dev1/Ctr0Out", "Dev1/port0/line0", DAQmx_Val_DoNotInvertPolarity);

 

However when I called the route function, an error cocurred, "Terminal for the device is invalid", Status code: -89129. I tried many terminal names such as PFI12, Ctr0InternalOutput, ctr0, ......, and they all returned this same error.

 

   Thanks.

  Penn

 

0 Kudos
Message 3 of 7
(4,115 Views)

Dear Nathan:

 

    DAQmxConnectTerms("/Dev1/Ctr0Source", "/Dev1/PFI0", DAQmx_Val_DoNotInvertPolarity);

    This statement is OK.

    But does it route ctr0 counter to Dev1/port0/line0 ?

    Because I cannot get change dection signal event on Dev1/port0/line0.

 

The snippet of code lists below:

 

//generate the pulse train:   

    DAQmxErrChk (DAQmxCreateTask("",&taskHandle));
    DAQmxErrChk (DAQmxCreateCOPulseChanFreq(taskHandle,"Dev1/ctr0",  //const char counter[]  //, Dev1/ctr1
                                            "", //nameToAssignToChannel
                                            DAQmx_Val_Hz, //units
                                            DAQmx_Val_Low, //idleState
                                            2.0,   //initialDelay
                                            1,     //freq
                                            0.5)); //dutyCycle

    DAQmxSetSampTimingType (taskHandle, DAQmx_Val_Implicit);
    DAQmxErrChk (DAQmxConnectTerms("/Dev1/Ctr0Source", "/Dev1/PFI0", DAQmx_Val_DoNotInvertPolarity));
    DAQmxErrChk (DAQmxStartTask(taskHandle));

 

//changedetection

{
    int32       error=0;
    char        errBuff[2048]={'\0'};

    DAQmxErrChk (DAQmxCreateTask("",&taskHandle));
    DAQmxErrChk (DAQmxCreateDIChan(taskHandle,"Dev1/port0/line0","",DAQmx_Val_ChanPerLine));
    DAQmxErrChk (DAQmxCfgChangeDetectionTiming(taskHandle,"Dev1/port0/line0","Dev1/port0/line0",DAQmx_Val_ContSamps,1));
    
    DAQmxErrChk (DAQmxRegisterSignalEvent(taskHandle,DAQmx_Val_ChangeDetectionEvent,0,ChangeDetectionCallback,NULL));
    DAQmxErrChk (DAQmxStartTask(taskHandle));

Error:
    if( DAQmxFailed(error) )
    {
        DAQmxGetExtendedErrorInfo(errBuff,2048);
        DAQmxStopTask(taskHandle);
        DAQmxClearTask(taskHandle);
        taskHandle = 0;
        MessageBox(errBuff);
    }
}   

 

Thanks a lot.

Penn

0 Kudos
Message 4 of 7
(4,107 Views)

I may be confused with your code, but you don't want to route "ctr0 counter to Dev1/port0/line0".  If I understand your question correctly, you just want to have a callback method called when the AI Start Trigger Event happens?  In that callback method you can do any other code you wan to do. (must be light weight)

 

If so, then you will want to route the AI Start Task (Dev1/ai/StartTrigger) to Dev1/PFI0 and then use Dev1/PFI0 as the line you use in your DI task.  And then register the callback.  You don't need to use a counter in between all that.  

 

I used the following to understand how to implement the DI Change Detection:

http://forums.ni.com/t5/Digital-I-O/Using-DAQmxRegisterSignalEvent-CallBack-in-C/td-p/2037114

http://www.ni.com/white-paper/4102/en

 

-Nathan

Systems Engineer
SISU
0 Kudos
Message 5 of 7
(4,096 Views)

Dear Nathan:

  Thanks for your reply.

 

  I tried your suggestion. The snippet of code listed below:

 

void RegisterEvent()

{
    int32       error=0;
    char        errBuff[2048]={'\0'};

    DAQmxErrChk (DAQmxConnectTerms("/Dev1/ai/StartTrigger", "/Dev1/PFI0", DAQmx_Val_DoNotInvertPolarity));

    /*********************************************/
    // DAQmx Configure Code
    /*********************************************/
    DAQmxErrChk (DAQmxCreateTask("DI",&taskHandle));    
    DAQmxErrChk (DAQmxCreateDIChan(taskHandle,"/Dev1/port1/line0","",DAQmx_Val_ChanPerLine));
    DAQmxErrChk (DAQmxSetBufInputBufSize(taskHandle, 0));    
    DAQmxErrChk (DAQmxCfgChangeDetectionTiming(taskHandle,"/Dev1/port1/line0","/Dev1/port1/line0",DAQmx_Val_ContSamps,1));    
    DAQmxErrChk (DAQmxRegisterSignalEvent(taskHandle,DAQmx_Val_ChangeDetectionEvent,0,ChangeDetectionCallback,NULL));    
    DAQmxErrChk (DAQmxStartTask(taskHandle));

Error:
    if( DAQmxFailed(error) )
    {
        DAQmxGetExtendedErrorInfo(errBuff,2048);        
        DAQmxStopTask(taskHandle);
        DAQmxClearTask(taskHandle);
        taskHandle = 0;
        MessageBox(errBuff);
        DAQmxErrChk (DAQmxDisconnectTerms("/Dev1/ai/StartTrigger", "/Dev1/PFI0"));
    }
}

 

  My A/D card is X serires. I think "/Dev1/PFI0" refer to "/Dev1/port1/line0"

 

  The funtion returned the following error:

  Resource requested by this task has already been reserved by a different task. Status Code: -200022.

 

  Thank you very much.

 

 Penn

0 Kudos
Message 6 of 7
(4,077 Views)
Solution
Accepted by topic author Dr.Penn

Which line of code is causing the error?  Also you might try changing all the "/Dev1/port1/line0" references to "/Dev1/PFI0".  In the pinout for your card it specifially using PFI0 notation, so its best to follow that.  You can see the device pinout information for your device in the Measurement and Automation Explorer.  If you right click on the card and select the option "Device Pinout".  Also you can see where to route signals when you select the device in the Device tree in MAX and at the bottom of the window there is a tab titled "Routing Tables" that shows all valid routing.  

 

You may have to internally route the signal to PFI1 and physically wire PFI1 to PFI0 and setup your DI task on PFI0.

 

I hope this helps!

 

-Nathan 

Systems Engineer
SISU
0 Kudos
Message 7 of 7
(4,065 Views)