From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

NI-DAQmx triggered analog input - is restart required each time?

Running a PCIe-6361 with NI-DAQmx 9.0.2, Windows XP.

I have a triggered system to acquire data from a single analog channel; I'd like to wait for the trigger, acquire 1000 samples,read it in, and repeat.

If I understand things properly, the only option that I have is to set the task for N=1000 samples, start the task, call DAQmxReadAnalogF64 to read the samples out, and then restart the task again. 

 

What I'd ideally like to do is to set up a "Done" event handler, start the task, and then when the event handler is called read out the data and simply tell the system to go again and wait for the next trigger. From DAQmxStartTask: "Starting and stopping a task repeatedly reduces the performance of the application." 

 

Am I understanding this right? 

0 Kudos
Message 1 of 9
(4,321 Views)

Hi pblase,

 

Have you had a chance to look in the Example Finder in CVI?  There are a few examples that show how to set a retriggerable property on tasks, one being ContAcq-IntClk-DigStart-Retrig.prj.  The command line I think you would be most interested in is this one:

 

DAQmxErrChk (DAQmxSetTrigAttribute(gTaskHandle,DAQmx_StartTrig_Retriggerable,1));

 

As long as your acquisitions are finite, you can use this property.  Let me know if this is what you were looking for, thanks!

Kyle A.
National Instruments
Senior Applications Engineer
0 Kudos
Message 2 of 9
(4,295 Views)

that seems to be it, but there are other problems.

For this part of it, I'm essentally trying to implement a digital o'scope. The card is a PCIe-6361, with a single signal coming into ai0, and a digital trigger comming into PFI0. I've set up an NI-DAQmx task appropriately in MAX and it works nicely. This task defines the NI-DAQmx buffer (1k samples), the triggering (Start Trigger = digital edge, PFI0, rising; no reference trigger), internal acquisition clock, no logging.

 

Here's what I've got so far:

In "DAQ_Handler.c" (which sets up and modularizes the DAQ system)

 

Open_System (on startup) {

    status = DAQmxLoadTask (ReceiverTask.TaskName, &ReceiverTask.DAQTask_Handle); //open the task and save the handle

    status = DAQmxRegisterDoneEvent (ReceiverTask.DAQTask_Handle, 0, CB_ReceiverDataDone, NULL);

         //where CB_ReceiverDataDone() is a routine to handle the data after it has been acquired

 

    status = DAQmxGetBufferAttribute (ReceiverTask.DAQTask_Handle,
                                      DAQmx_Buf_Input_BufSize,
                                      &defaultBufferCount); //how big of a buffer should I allocate for the data?
    ReceiverTask.DataBuffer = (float64 *)calloc ((size_t)defaultBufferCount, sizeof(float64)); //allocate a local buffer for the data

}

 

Start_DAQ (when the program wants to start acquisition) {

    status = DAQmxStartTask (ReceiverTask.DAQTask_Handle);

}

 

Stop_DAQ (when the program wants to start acquisition) {

    status = DAQmxStopTask (ReceiverTask.DAQTask_Handle);

}

 

Close_System (on exit) {

    status = DAQmxClearTask (ReceiverTask.DAQTask_Handle);     //stops and clears task

    free (ReceiverTask.DataBuffer); //deallocate buffers
}

 

int32 CVICALLBACK CB_ReceiverDataDone (TaskHandle taskHandle, int32 status, void *callbackData) {
    //called when the task has finished collecting the requested number of samples.
    int32 ret_status;
    int32 samplesRead;
    int i, n;
   
    if (status == 0) { //successful completion

        /* //from the help file for DAQmxRegisterDoneEvent ()
        The status parameter contains the status of the task when the event occurred.
        If the status value is negative, it indicates an error.
        If the status value is zero, it indicates no error.
        If the status value is positive, it indicates a warning.
        */
        //read the data into ReceiverTask.DataBuffer
        ret_status = DAQmxReadAnalogF64 (taskHandle, DAQmx_Val_Auto, 0,
                                         DAQmx_Val_GroupByChannel,
                                         ReceiverTask.DataBuffer,
                                         ReceiverTask.DataToAcquire, &samplesRead, 0);
        ret_status = DAQmxStopTask (taskHandle); //stop it in preparation for the next line
        
        //how many samples actually acquired?
        ReceiverTask.DataSampleCnt = (uInt32)samplesRead;  
         if (samplesRead == 0) { //problem
            return (0);
        }

        //set the semaphore
        ReceiverDataReady = DAQ_TASK_DATA_RDY;
    
        //start the task for the next line
        if (ReceiverTask.Running) { //don't restart if the "stop" button has been pushed
            ret_status = DAQmxStartTask (taskHandle);
        }

        ....... //call some other stuff to process the data in ReceiverTask.DataBuffer[]
   
    //done
    return (0);
}

The problem at the moment is that CB_ReceiverDataDone only gets called about every second or so, when it should be more or less continous. I'm feeding in a 1 kHz sawtooth with a synchronized digital trigger. If I make this retriggerable, do I not have to start and stop it?

0 Kudos
Message 3 of 9
(4,158 Views)

Hello,

 

When you set an acquisition retriggerable, you tell the driver how many samples you would like to sample and at what rate, and that time equivocates to a certain amount of time.  For example, acquiring 1000 samples at 1kHz sampling rate will mean every trigger will take 1 second of data before it stops, and waits for the next trigger.  You don't have to stop a finite acquisiton; it will stop when it is done acquiring.  During this period of time, you ignore other triggers that come in until the previous triggered acquistion completes.

 

 

Kyle A.
National Instruments
Senior Applications Engineer
0 Kudos
Message 4 of 9
(4,139 Views)

Thanks.

what happens if the event handler is off doing things (like plotting to the screen) when the next trigger occurs?

0 Kudos
Message 5 of 9
(4,089 Views)

Hello pblase,

 

Since you are using retriggerable property, it will be controlled by the card itself instead of your program. Knowing this, it will not be affected by plotting data to a screen or things like this.


Jim St
National Instruments
RF Product Support Engineer
0 Kudos
Message 6 of 9
(4,062 Views)

I posted the problem in a new post, since I uploaded the code and consolodated a few things.

Does calling DAQmxSetTrigAttribute scrub all of the other trigger attributes set up in MAX? That might explain what's going on.

0 Kudos
Message 7 of 9
(3,962 Views)

There is nothing I can see that would indicate setting a trigger attribute negates all other trigger attribute set in MAX.  When you bring in a task from MAX, those parameters act as the defaults for the task, and they can be modified in your coding.  DAQmxSetTrigAttribute is only targeting a single property selected by the int32.

 

From the documentation:

 

23446iC2284F1C8285B2C4

Kyle A.
National Instruments
Senior Applications Engineer
0 Kudos
Message 8 of 9
(3,928 Views)

Thanks. I've been poking around, and this thing is definitely not triggering like it's supposed to.

0 Kudos
Message 9 of 9
(3,925 Views)