Counter/Timer

cancel
Showing results for 
Search instead for 
Did you mean: 

Reading Multiple Counters Simultaneously

Hello,
 
I am using a PCI 6602 to take buffered period measurements on multiple TTL pulse waves.  I would like to read these waves simultaneously, starting and stopping on the same measurement.  I am writing the code in MATLAB and wanted to know what steps and functions I should be using to read two or more counters simultaneously.
 
This is what I have working for one counter:
Create Task
Create Channel (DAQmxCreateCIPeriodChan)
Configure Clock (DAQmxCfgImplicitTiming - continuous)
Start Task
Pause
Read Channel (DAQmxReadCounterF64)
Stop Task
 
If I double the code up, to have two tasks each with a different counter, the counters start with a delay to each other.  If I need a trigger, what kind should I use?
 
-Mike
0 Kudos
Message 1 of 9
(4,874 Views)

Not to be pedantic, just trying to be clear.

1. You (probably) do not truly need to "read" simultaneously.  Rather, you need a means to capture and read such that the data is correlated / synced in time.

2. This is a bit more problematic for period measurement because measurement time is not under your control.  It is implicit in the signals being measured.

3. I program with LabVIEW and don't know how to configure tasks from within Matlab.

4. All that said, the first step is to configure all the period measurement tasks to use an "Arm Start" trigger.  They should all get triggered by the same signal, which may be something you control.  On a 6602, I often generate an edge using DIO 0, which is also known as PFI 0 when specifying the Arm Start Trigger terminal.

5. Start the counter tasks before generating the trigger edge.  Then both of them will start counting time simultaneously.

6. When you read the buffers of periods, you may need to do some post-processing to trim the data down.  The cumulative sum of the periods will be the timestamp associated with each period measurement.  The two counters' timestamp values will probably all be different, and one will contain later data than the other which you may want to trim.

-Kevin P.

CAUTION! New LabVIEW adopters -- it's too late for me, but you *can* save yourself. The new subscription policy for LabVIEW puts NI's hand in your wallet for the rest of your working life. Are you sure you're *that* dedicated to LabVIEW? (Summary of my reasons in this post, part of a voluminous thread of mostly complaints starting here).
0 Kudos
Message 2 of 9
(4,867 Views)
It's ok.  The more detail you have, the better I may solve my problem.
 
1.  You're right.  I don't need to "read" the data simultaneously.  By read I meant gathering samples to the task, not reading the samples to an array.  So I really need to start the tasks simultaneously.
 
2.  Can it still be done?
 
3.  As long as I know which DAQmx functions to use and the order to use them, I can work at it from there.
 
4.  What is the DAQmx function for an Arm Start.  The only ones that are made clear are an Edge Trigger and a Pattern Trigger.  By generating an edge do you mean generating a pulse wave.  If so, do you use the same line as a DIO or do you route from one pin to another?
 
5.  That makes sense.
 
6.  Are you saying that I will have to shift the data to have it match properly?  That index_5 on counter_0 will be the same as index_13 on counter_1?  Or are you saying that one counter may have more samples than the other?
 
-Mike
0 Kudos
Message 3 of 9
(4,865 Views)
2.  You can start the tasks simultaneously.  You can end the tasks sequentially and almost simultaneously.  But the actual measurement times depend entirely on the external signals being measured.  In general, *none* of the period measurements will correlate exactly in time.  The measurement happens whenever the edge happens to occur.
 
4. The "Arm Start" function is for Counter tasks only.  You seem to be looking at functions for Digital tasks.  Counter tasks are treated as an entirely distinct category from Digital tasks.  Counter tasks are typically more suited to edge-sensitive and timing functions while Digital are typically more suited to state-sensitive matters.
   There's also some chance the "Arm Start" capability just isn't exposed in Matlab.
 
6.  index_5 on counter_0 will probably not match the time of *any* index on counter_1.  Periods are measured when the external signals produce active edges.  The "sample rate" is not constant unless the signal has a constant frequency.  If one signal has a higher frequency than the other, the result will be more measurements in the data acq buffer.
 
-Kevin P.
CAUTION! New LabVIEW adopters -- it's too late for me, but you *can* save yourself. The new subscription policy for LabVIEW puts NI's hand in your wallet for the rest of your working life. Are you sure you're *that* dedicated to LabVIEW? (Summary of my reasons in this post, part of a voluminous thread of mostly complaints starting here).
0 Kudos
Message 4 of 9
(4,861 Views)
Well assuming that I can make an Arm Trigger in the code, what pins should I use to to create a Pulse wave for the trigger?  Would it be possible to use the same pin to output the signal to and use it as a tirgger, to make an internal trigger of sorts?
0 Kudos
Message 5 of 9
(4,859 Views)

Yes you can.  This was what I was driving at, not successfully, in item #4 of my first post.

The pin assigned for DIO 0 is the *same* pin known as PFI 0.  You can make a Digital Output task using Dev_X_/port0/line0 which controls the state of that pin and can then assign a counter task to use the terminal PFI 0 as the Arm Start trigger terminal.  Since they are the same physical pin, there's no screwdriver work.

It would also be possible to generate a single pulse on a spare counter and use that counter's output as the Arm Start trigger.  Again, no screwdriver work.

-Kevin P.

CAUTION! New LabVIEW adopters -- it's too late for me, but you *can* save yourself. The new subscription policy for LabVIEW puts NI's hand in your wallet for the rest of your working life. Are you sure you're *that* dedicated to LabVIEW? (Summary of my reasons in this post, part of a voluminous thread of mostly complaints starting here).
0 Kudos
Message 6 of 9
(4,850 Views)

So I tried something out and it didn't work.  In words, I tried to create a signal to PFI0 (task 3) to trigger Ctr0 and Ctr1 (task 1 and 2).  I'm going to paste it in here and maybe you'll ahve a few comments for me.   I'm only pasting the pertinent trigger code.  The code to create/read in the counters is fine.

%Create Digital Output Task

taskh3 = uint32(1);
[err21,A,taskh3] = calllib(
'myni','DAQmxCreateTask','',taskh3);
[err22] = calllib(
'myni','DAQmxCreateDOChan',taskh3,'Dev1/port0/line0','',DAQmx_Val_ChanPerLine)
[err33] = calllib(
'myni','DAQmxSetSampTimingType',taskh3,DAQmx_Val_OnDemand)

%Define Variables for Write

nsamples3 = 1;
wArray = uint32(1);
pwArray = libpointer(
'uint32Ptr',wArray);
samps3 = nsamples3;
pSamps3 = libpointer(
'int32Ptr',samps3);
empty3 = [];
pEmpty3 = libpointer(
'uint32Ptr',empty3);

%Define Write


[err31,a,b,c] = calllib(
'myni','DAQmxWriteDigitalU32',taskh3,nsamples,false,10.0,DAQmx_Val_GroupByChannel,wArray,pSamps3,pEmpty3)

%Define Trigger Properties


[err23] = calllib(
'myni','DAQmxSetArmStartTrigType',taskh1,DAQmx_Val_DigEdge)
[err31] = calllib(
'myni','DAQmxSetDigEdgeArmStartTrigEdge',taskh1,DAQmx_Val_Rising)
[err24] = calllib(
'myni','DAQmxSetDigEdgeArmStartTrigSrc',taskh1,'Dev1/port0/line0')
[err25] = calllib(
'myni','DAQmxSetArmStartTrigType',taskh2,DAQmx_Val_DigEdge)
[err32] = calllib('myni','DAQmxSetDigEdgeArmStartTrigEdge',taskh2,DAQmx_Val_Rising)
[err26] = calllib(
'myni','DAQmxSetDigEdgeArmStartTrigSrc',taskh2,'Dev1/port/line0')

%Start Tasks

[err04] = calllib(
'myni','DAQmxStartTask',taskh1);
[err14] = calllib(
'myni','DAQmxStartTask',taskh2);
[err27] = calllib('myni','DAQmxStartTask',taskh3);

 

When this runs I get an error (-89120) on both task1 and task2 start functions and read functions.  The error info says:

Source terminal to be routed could not be found on the device.

Make sure the terminal name is valid for the specified device. Refer to Measurement & Automation Explorer for valid terminal names.
Property: DAQmx_DigEdge_ArmStartTrig_Src
Property: DAQmx_DigEdge_ArmStartTrig_Edge
Source Device: Dev1
Source Terminal: Dev1/port0/line0

Task Name: _unnamedTask<1F>

Status Code: -89120

Any clues?

0 Kudos
Message 7 of 9
(4,834 Views)

Yep.  I don't know the syntax for text-based language DAQmx calls, but you need to specify ArmStartTrigSrc in terms similar to "dev1/PFI0" and not in terms meant for digital i/o terms such as port0/line0.  This may seem silly since they map to the same physical pin on the 6602.  However, that isn't true on other boards.  Only terminals designated as PFI can be connected to the edge-sensitive triggering circuitry.  So when configuring the trigger, you have to refer to the pin in terms of its PFI identity.

-Kevin P.

 

CAUTION! New LabVIEW adopters -- it's too late for me, but you *can* save yourself. The new subscription policy for LabVIEW puts NI's hand in your wallet for the rest of your working life. Are you sure you're *that* dedicated to LabVIEW? (Summary of my reasons in this post, part of a voluminous thread of mostly complaints starting here).
0 Kudos
Message 8 of 9
(4,830 Views)

PHEW, I finally got it to work.  My problem for the longest time was figuring out what to call the trigger pin.  So the DO is written to "Dev1/port0/lin0" while the trigger is read from simply "PFI0".  Not "Dev1/PFI0".  Not "Dev1/port0/PFI0".  Simply "PFI0".  Thanks for your help Kevin.  You've been awesome.

-Mike

0 Kudos
Message 9 of 9
(4,821 Views)