Counter/Timer

cancel
Showing results for 
Search instead for 
Did you mean: 

Count pulses with DAQmx ANSI C

I have an externally-generated sampling signal and I need to count how many pulses occur between each edge of the sampling signal, where this count will very often be zero.  This is similar to photon-counting applications that have been posted on this board, but I need to accomplish it using the C API (not Labview).  I'm using an NI-6251 card and NI-DAQ 7.4.

 

From everything I've read I want to use Buffered Period Measurement (with Duplicate Count Prevention enabled), but I cannot get code to work for this.

 

For testing I have a 16 kHz pulse train wired to CTR0 GATE (PFI9) for my sampling signal and a 100 Hz pulse wired to CTR0 SRC (PFI8) to simulate my input that I need to count.

 

My code looks like this:

 

const int   SamplesPerSecond = 16130;

float64     TimeoutSeconds = 20.0;

float64     Pulses[SamplesPerSecond] = {0};

TaskHandle  CounterTaskHandle = 0;

DAQmxErrChk(DAQmxCreateTask("PulseCount_C", &CounterTaskHandle));
DAQmxErrChk(DAQmxCreateCIPeriodChan(CounterTaskHandle,      // Task Handle
                                    "Dev1/ctr0",            // Counter
                                    "",                     // Name to assign channel
                                    0.00001,                // Minimum expected value
                                    100,                    // Maximum expected value
                                    DAQmx_Val_Ticks,        // Units
                                    DAQmx_Val_Rising,       // Edge to trigger on
                                    DAQmx_Val_LowFreq1Ctr,  // Measurement method
                                    1,                      // Measurement time
                                    4,                      // Divisor
                                    "")                     // Custom scale name
);
DAQmxErrChk(DAQmxCfgImplicitTiming(CounterTaskHandle,
                                   DAQmx_Val_ContSamps,    // Acquire or generate samples until you stop the task.
                                   SamplesPerSecond)       // Samples per channel to aquire
);
DAQmxErrChk(DAQmxSetCIDupCountPrevent(CounterTaskHandle, "Dev1/ctr0", 1));
DAQmxErrChk(DAQmxStartTask(CounterTaskHandle));

// Loop over the next statement

DAQmxErrChk(DAQmxReadCounterF64(CounterTaskHandle,   // Task handle to read data from
                                SamplesPerSecond,    // The number of samples, per channel, to read
                                TimeoutSeconds,      // timeout, in seconds
                                Pulses,              // The array to read samples into
                                SamplesPerSecond,    // Array size, in samples
                                &readD,              // The actual number of samples read from each channel
                                0                    // reserved
));
 

The ReadCounter call is blocking for 1 second as if everything is working, but the Pulses array contains all zeros.

 (Oddly, if I remove the call to  DAQmxSetCIDupCountPrevent() aquisition still takes 1 second but the values I get back are all 4960, plus or minus one. I have no idea where this number comes from, and it doesn't change if I increase the frequency of my data signal.)

 

I can pretty much get things working with edge counting mode, but I don't really want a cumulative count; period measurement should give me exactly what I want without any post-processing (or so the docs say).

 

Can anyone explain what I'm doing wrong?

0 Kudos
Message 1 of 4
(4,660 Views)

Your gate is moving way to quickly at 16 kHz to be able to count anything on your 100 Hz Source.  Check out the following Dev Zone Article.

 

http://zone.ni.com/devzone/cda/tut/p/id/2868

Doug Farrell
Solutions Marketing - Automotive
National Instruments

National Instruments Automotive Solutions
0 Kudos
Message 2 of 4
(4,644 Views)

Thanks for your reply Doug.

 

I understand that for a "typical" period-measurement application I would have the faster signal as the source and the slower as the gate (as pictured in the Dev Zone article you referenced) so that I get the period of the gate as a multiple of the period of the source.

 

My intention, however, is to hook up the signals in reverse.  So for the majority of the 16000 samples I will have zero counts, but 100 times a second I'll capture an edge and get a single count.

 

This post seems to imply that this should work:

http://forums.ni.com/ni/board/message?board.id=40&thread.id=1974&view=by_date_ascending&page=1#M205

 

In fact that thread describes pretty much exactly what I want to do, except all the discussed code is in LabView and I need to do it from C.

0 Kudos
Message 3 of 4
(4,640 Views)

Upon playing with this some more, I've discovered that the default sampling signal is not PFI8, but the 80MHz timebase.  Once I explicitly set the source to my 100 Hz signal with

 

DAQmxErrChk(DAQmxSetCICtrTimebaseSrc(CounterTaskHandle, "/Dev1/ctr0", "/Dev1/PFI8"));

 

Things are working as I expected.

Message Edited by esci on 03-05-2009 06:00 PM
0 Kudos
Message 4 of 4
(4,638 Views)