counting pulses with NI DAQ tools

Hi,

I am using IGOR 6.21 together with NI DAQ tools. The NI DAQ hardware I am using is a PCMCIA 6036E board.
I would like to do the following: counting pulses with counter 0 on the board over a specified period - e.g. 1 second.
For testing my code I am using the channel "/Dev1/20MHzTimebase" of the NI board as a source. First, I tried the following function:
function count_pulses_simple()

    Variable/D a
       
    DAQmx_CTR_CountEdges/DEV="Dev1" /EDGE=1 /INIT=0 /DIR=1 /SRC="/Dev1/20MHzTimebase"  0    
   
    sleep 00:00:01     
       
    a = fDAQmx_CTR_ReadCounter("Dev1", 0)
   
    fDAQmx_CTR_Finished("Dev1", 0)
   
    print a
   
end

It returns e.g. 4.53663e+06, however, this value varies, most likely because the sleep function is not very accurate. What bothers me is, why does the function not return a number which is close to 2e+7 and therefore corresponding to the 20MHz timebase? Is this due to a numeric overflow or due to aliasing?

In order to have a more precise timing for the counting I also tried another procedure instead of using the sleep function. For this, I tried to use counter 1 on the same NI board to provide a trigger (on "/Dev1/Ctr1InternalOutput") for counter 0. The trigger (/TRIG) command should be used to start the counting and the pause (/PAUS) command should terminate it. With the following function it should count for 0.1s:
function count_pulses()

    Variable/D a
       
    DAQmx_CTR_CountEdges/DEV="Dev1" /EDGE=1 /INIT=0 /DIR=1 /TRIG={"/Dev1/Ctr1InternalOutput", 1, 1} /PAUS={"/Dev1/Ctr1InternalOutput", 0, 0, 0, 2} /SRC="/Dev1/20MHzTimebase"  0           
   
    DAQmx_CTR_OutputPulse/DEV="Dev1" /SEC={0.1, 0.9} /NPLS=1 /OUT="/Dev1/Ctr1InternalOutput" 1
       
    a = fDAQmx_CTR_ReadCounter("Dev1", 0)
   
    fDAQmx_CTR_Finished("Dev1", 0)
    fDAQmx_CTR_Finished("Dev1", 1)
   
    print a
   
end

However, when running this function an error message appears which is related to the use of the /TRIG command. If the /TRIG command is removed no error message appears but the timing doesn't seem to have any effect - the result is completely independent on the /SEC settings.

Any help would be greatly appreciated!

Andreas
Andreas-

You are correct that count_pulses_simple() fails to give the expected result due to overflow. The E-series devices have 24-bit counters; 2^24=16777216. Given that, you would expect that an exact 1-second counting time would result in 20e6-16777216 = 3.22278e+06; I think the result you got is not unreasonable as the sleep time and execution time of the statements would be pretty variable.

If you change 20MHzTimebase to 100kHzTimebase the numbers you get will be quite variable but right around 100,000. Note that 20 MHz is the maximum counting rate specified for that device.

I added some error checking and corrected the commands in your count_pulses() function:
function count_pulses()
 
    Variable/D a
 
    try
//      DAQmx_CTR_CountEdges/DEV="pci6014" /EDGE=1 /INIT=0 /DIR=1 /TRIG={"/pci6014/Ctr1InternalOutput", 1, 1} /PAUS={"/pci6014/Ctr1InternalOutput", 0, 0, 0, 2} /SRC="/pci6014/20MHzTimebase"  0; AbortOnRTE
        DAQmx_CTR_CountEdges/DEV="pci6014" /EDGE=1 /INIT=0 /DIR=1 /PAUS={"/pci6014/Ctr1InternalOutput", 1, 0} /SRC="/pci6014/20MHzTimebase"  0; AbortOnRTE
     
//      DAQmx_CTR_OutputPulse/DEV="pci6014" /SEC={0.1, 0.9} /NPLS=1 /OUT="/pci6014/Ctr1InternalOutput" 1; AbortOnRTE
        DAQmx_CTR_OutputPulse/DEV="pci6014" /SEC={.1,1} /NPLS=1 1; AbortOnRTE
       
        sleep/S 2
     
        a = fDAQmx_CTR_ReadCounter("pci6014", 0); AbortOnRTE
     
        fDAQmx_CTR_Finished("pci6014", 0); AbortOnRTE
        fDAQmx_CTR_Finished("pci6014", 1); AbortOnRTE
    catch
        if (V_abortCode == -4)
            print "Error trying to count edges:"
            print fDAQmx_ErrorString()
        endif
    endtry
 
    print a

end

Adding the error checking resulted in an error message telling me that /TRIG is not supported on that device for counting pulses. The /PAUS trigger is supported, however, but an error in my documentation has led you astray. The documentation has these arguments for /PAUS:

/PAUS={source, pretrigSamples [, type, edgeslopewhen, level1, level2]}

But in fact, the pretrigSamples argument is not present in the PAUS keyword; it is used only for a reference or stop trigger for pre-triggered analog input. My apologies.

Also, the type for /PAUS must be 1; a type of 0 disables the trigger. Finally, the sense of the /PAUS trigger is perhaps unexpected- when asserted, it *stops* the counter. So for a pulse that is high, you need to use 0 for the level argument in order to have counting occur during the high-going part of the pulse.

Finally, I added the Sleep command because otherwise execution gets to fDAQmx_CTR_ReadCounter() and the rest too soon, before the pulse time is elapsed. Then you get a truncated count.

I removed "/OUT="/pci6014/Ctr1InternalOutput"" because it is unnecessary- that happens regardless of any other settings.

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com