Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

Reading finite digital samples from a continuous digital write task

I am using PXIe6368, and testing digital I/O on breakout board SCB-68A. 4 lines are dedicated for digital write, and 4 lines for read. On the breakout board, the digital output lines are connected to input lines. My program is in text based C API and this is the program operation steps are as follows:

 

1. Create digital output task, and DO channels with 4 lines.

2. The internal sample clock is set as timing source with continuous sampling (sampleMode=DAQmx_Val_ContSamps)

3. Call the digital write function ,and start the digital task.

 

4. Create digital input task, and DI channels with 4 lines.

5. The internal sample clock is set as timing source with finite sampling (sampleMode=DAQmx_Val_FiniteSamps)

6. Start the digital input task.

7. Call the digital read function in a for loop 4 times.

 

My question is what is the difference in digital input with finite sampling and continuous sampling? Does finite sampling acquire data only once in buffer? If finite sampling is used, and I call read function 4 times, will the read data be the same all 4 times?

How are the finite sampling buffer size, and the read array in read function related?

 

Below is my complete code for reference:

dataDO =             [
                        0x00000000,
                        0x00000010,
                        0x00000020,
                        0x00000030,
                        0x00000040,
                        0x00000050,
                        0x00000060,
                        0x00000070,
                        0x00000080,
                        0x00000090,
                        0x000000a0,
                        0x000000b0,
                        0x000000c0,
                        0x000000d0,
                        0x000000e0,
                        0x000000f0]*2;

multDO = 1;
nsmpls = dataDO.size*multDO;
dataDI = numpy.zeros(nsmpls+1, dtype=numpy.uint32)

 
    ##### Begin Digital Output #####
    # DAQmx Configure Code
    DAQmxCreateTask("taskDO",  byref(taskHandleDO))
    DAQmxCreateDOChan(taskHandleDO,
                    "Dev1/port0/line4:7",
                    "", DAQmx_Val_ChanForAllLines)

    # DAQmx Timing Setup
    DAQmxCfgSampClkTiming(taskHandleDO, "", freq_master,
                            DAQmx_Val_Rising, DAQmx_Val_ContSamps,
                            dataDO.size*multDO)

    wrtDig = c_int(0)

    # DAQmx Write Code
    DAQmxWriteDigitalU32(taskHandleDO, dataDO.size*multDO, 0, 10.0,
                            DAQmx_Val_GroupByChannel,
                            dataDO, byref(wrtDig), None)
    #DAQmxStartTask(taskHandleDO)

    #Start output at trigger, the trigger in in taskHandleCtrTrig
    DAQmxCfgDigEdgeStartTrig( taskHandleDO, "/Dev1/PFI14", DAQmx_Val_Rising);  
 
    ##### End Digital Output #####
    ##### Begin Digital Input #####
    DAQmxCreateTask("taskDI",  byref(taskHandleDI))
    DAQmxCreateDIChan(taskHandleDI,
                    "Dev1/port0/line0:3",
                    "", DAQmx_Val_ChanForAllLines)

    # DAQmx Timing Setup
    DAQmxCfgSampClkTiming(taskHandleDI, "", freq_master,
                            DAQmx_Val_Rising, DAQmx_Val_FiniteSamps,
                            #DAQmx_Val_Rising, DAQmx_Val_ContSamps,
                            dataDO.size)


    #Start output at trigger, the trigger in in taskHandleCtrTrig
    DAQmxCfgDigEdgeStartTrig( taskHandleDI, "/Dev1/PFI12", DAQmx_Val_Rising);  
    DAQmxSetReadRelativeTo(taskHandleDI, DAQmx_Val_FirstSample )

    ##### End Digital Input #####

    ##### Begin Counters Used is Triggers #####
    DAQmxCreateTask("taskCtrTrig",  byref(taskHandleCtrTrig))
    DAQmxCreateCOPulseChanTime( taskHandleCtrTrig, "Dev1/ctr2", "",
                                DAQmx_Val_Seconds, DAQmx_Val_Low,
                                0.001,0.50e-3,1.00e-6);
    DAQmxCreateCOPulseChanFreq(taskHandleCtrTrig, "Dev1/ctr0", "",
                                DAQmx_Val_Hz, DAQmx_Val_High,
                                180.0e-9,
                                freq_master/40, 0.10)   #Read trigger clk

    # DAQmx Timing Setup
    DAQmxCfgImplicitTiming(taskHandleCtrTrig, DAQmx_Val_ContSamps, 2)
    ##### End Counters Used is Triggers #####
 
    # DAQmx Start Code
    DAQmxStartTask(taskHandleDO)
    DAQmxStartTask(taskHandleDI);
    DAQmxStartTask(taskHandleCtrTrig)
    DAQmxReadDigitalU32(taskHandleDI, nsmpls, 30e-0,
            DAQmx_Val_GroupByChannel, dataDI, nsmpls,
            byref(written), None);
    read_2d = array(shape=(4, nsmpls+1), dtype = uint);
    for x in range( 0, 4):
        DAQmxReadDigitalU32(taskHandleDI, nsmpls+0, 30e-0,
                DAQmx_Val_GroupByChannel, dataDI, nsmpls,
                byref(written), None);
        read_2d[x, :] = dataDI;
        dataDI = numpy.zeros(nsmpls+1, dtype=numpy.uint32)

    print("dataDI", dataDI)
    print("read_2d", read_2d)
    sys.stdin.read(1) 

Thanks,

 

0 Kudos
Message 1 of 2
(2,240 Views)

(See also my suggestions about sync in your related thread.)

 

Finite Sampling:

- actual task buffer size is set when you configure sample clock timing.  An input task will sample until the buffer is filled and then stop sampling.  Data waits there in the task buffer until you call a Read function (or stop or clear the task).   Only DAQmx gets direct access to the task buffer, not your app.

- each time you call DAQmxRead to retrieve data from the task buffer, DAQmx will start from wherever you left off on the previous read.  Initially, it starts at the beginning with the first sample.

   If you read the entire buffer all at once, I *expect* (but can't test now) a subsequent read will recognize that you "left off" at the end of the buffer and will return no data at all.  It may give you an error when you attempt it.  It should *not* return the same data a second time.

- the array you designate in the call to DAQmxRead needs to be big enough to hold all the samples you requested.  It doesn't necessarily have to be as big as the task buffer.

 

Continuous Sampling:

- there are other distinctions too, the one I'll point out is that DAQmx treats the task buffer as circular.  If it wraps around to the point where it's about to overwrite data you have not yet read, it'll throw an error.  So on average, you need to plan to read data out of the buffer as fast as the task & driver are filling it. 

   A common recommendation is to repeatedly request about 1/10th sec worth of samples at a time in a loop.  If your app software "catches up", DAQmx will just wait long enough for the next 1/10th sec of samples to accumulate before returning them.

 

 

-Kevin P

ALERT! LabVIEW's subscription-only policy came to an end (finally!). Unfortunately, pricing favors the captured and committed over new adopters -- so tread carefully.
Message 2 of 2
(2,212 Views)