Counter/Timer

cancel
Showing results for 
Search instead for 
Did you mean: 

highly accurate timing stamping with 6602

Hi,

We recently purchased a 6602 counter/timer board to be used in a quantum key distribution experiment. What I'd like to do with it is some highly accurate (hopefully as fast as the clock 80MHz -> 12.5ns) time stamping. I have a vague idea of what I should do, but it's been a while since I used LabView, so if someone could point me in the right direction with some resources and examples that would be great. What I'm thinking is that I start the experiment with a trigger, then one counter channel gets the 80MHz clock as input, every time a second counter channel gets an event I stamp that event with the clock count and dump the time stamp and event to a file (excel or just a big long txt list). Does that sound about right? Any good examples of how to access the clock on this board with LabView, and any other code or ideas that I might need?

Thanks,
Chris
0 Kudos
Message 1 of 9
(7,476 Views)
Hello Chris,

I think the best way to get accurate timestamping is to use buffered event counting.
http://zone.ni.com/devzone/conceptd.nsf/webmain/51113501fbb9b10986256802007b8aa3

This will work if you can use the event occuring on the second counter channel to act as the external clock (or gate) of the first counter channel. Every time that the event occurs, you will latch the count register of the first counter into the buffer.

An example of buffered event counting using DAQmx installs with LabVIEW and the DAQmx driver. It can be found at the following File Path.
C:\Program Files\National Instruments\LabVIEW 7.1\examples\DAQmx\Counter\Count Digital Events.llb

There are two buffered event counting examples in the LLB.

Take care,
E.Lee
Eric
DE For Life!
0 Kudos
Message 2 of 9
(7,463 Views)
Hi again,

Thanks for help. I understand conceptually what I'm supposed to do. Now it's a question of doing it. I've been fooling around with the DAQmx Trigger control and trying to get it to work and searching for example code but haven't found much. Here's my sequence of things: Create Channel, Start Task, Start Trigger, Read, Stop Task, and Clear. The trigger and read are inside a while loop because what I'm intending is to have this continually running and time stamping events which are coming in as TTL pulses. What I'm trying to do is make it so that channel 0 has the 80MHz timebase coming into it, then since I'm trying to timestamp events, I'm putting the line with events on it in as my gate/trigger for channel 0. Then when an event happens channel 0 src has the current count in the time base. I realize that the counter will overflow with the 80MHz single pretty fast, I'll deal with that later (suggestions are welcome). For now I need to know how to use the trigger properly, also the previous post said that I needed to use a buffered input (so that I don't have software latency issues?). I looked at the two buffered examples but there isn't a good description of what's going on and why things are connected up as they are and what function they play. Any more resources I can learn from or explanations?

Thanks for any help,
Chris
0 Kudos
Message 3 of 9
(7,453 Views)
Hello Chris,

I was looking back at out discussion and I think I might have made things more confusing than they could be and I think there is a simpler way to accomplish what you are trying to do.

1) Buffered Event Counting - For our particular appilcation, buffered event counting will allow us to a) count events at both the source and the gate of the counter (I will explain in a second) and b) let us know the amount of time between consecutive events on the gate or the counter. The count register will always hold the number of active edges that have been input into the source terminal of the counter. In our case, we want to input the 80 MHz clock. Because we know the frequency of the signal (80 MHz) coming into the source terminal of the counter, we can determine the amount of time that has passed since the first active edge input on the source based on the current value in the count register. For example, if the count register has a value of 800,001, that means 800,001 active edges have been input into the source terminal at a frequency of 80 MHz, which means the timestamp for the 800,001st active edge is (800,001-1)/(80*10^6) = 0.01 s relative to the first active edge. In buffered event counting we also have a signal coming into the gate terminal of the counter. This signal is going to latch the data from the count register and store it into a buffer at every active edge. The size of this buffer will let us know how many active edges occured at the gate because for each active edge there should be one count register value in the buffer. Based on the actual values in the buffer, we can now calculate the timestamps for the active edges occuring on the gate. For example, let's say we receive an edge at the gate. We latch the count register and it has the value 2. We receive another active edge on the gate and we latch the count register value 500. That means that between those 2 active edges on the gate, the counter counted 498 edges at the source that were coming in at 80 MHz. The time between the two gate edges is 498/(80 MHz). Below is a timing diagram of buffered event counting.


Also, the LabVIEW example for buffered event counting can be found here:
C:\Program Files\National Instruments\LabVIEW 7.1\examples\DAQmx\Counter\Count Digital Events.llb\Count Digital Events-Buffered-Continuous-Ext Clk.vi

I've modified this example so that the source terminal of the counter uses the 80 MHz timebase. It is attached as "Buffered Event Counting.vi".

2) Large Range - In your most recent post you sounded concerned about reaching the terminal count of the count register when using the 80 MHz timebase. In order to avoid this, you can always route the output of the counter to the input of another counter. The output of a counter outputs a pulse whenever it reaches it's terminal count. We can use another counter to count the number of times we have hit the terminal count on the other counter.

3) Trigger - There is no direct way to trigger a counter measurement. However, you can control when the counter starts counting by determing when the active edges on the source terminal begin to appear. Counters can be used to generate pulse trains. You can use this pulse train instead of the 80 MHz timebase discussed in step 1) (however, you will not be able to generate a 80 MHz signal, the maximum will probably be 40 MHz). Since this pulse train can be triggered, you can effectively control when the counting begins. An example of this can be found here:
C:\Program Files\National Instruments\LabVIEW 7.1\examples\DAQmx\Counter\Generate Pulse.llb\Gen Dig Pulse Train-Continuous-Dig Start.vi

One thing to note is that setting up your event counting for a large range requires extra counters and doing a triggered pulse train generation also requires more counters. If your board only has 2 counters, you will not be able to do both.

I hope this information helps out, let me know if you have any other questions.

Message Edited by E.Lee on 06-03-2005 05:04 PM

Message Edited by E.Lee on 06-03-2005 05:05 PM

Eric
DE For Life!
Download All
Message 4 of 9
(7,436 Views)
Hi E.Lee,

Thanks so much for all the help you've given me. I'm going through the example you sent over and building up my application. I'm sure I'll have more questions, two that come to mind immediately are the following:

1) I have a PCI6602 counter/timer card, it has 8 counters on it. The experiment I'm doing has two detector sites, and at each site there are 4 detector channels. So that's 8 counters I need in total which is what I have. You mentioned a solution to when the counter overruns by hooking its output up to another counter, if I'm using all 8 counters then this isn't an option. Is there another way to do this? Can I update a variable with the number of overruns or something to that effect? When you talk about hooking up the output of one counter to another what are you talking about in terms of the block diagram code? Because all the code has DAQmx reads and writes, etc, but there's no block for the counter (other then the counter physical channel), so if I was to hook up the output of one counter to another one, how would I go about doing that? Oh and what is the counters size or how can I find that out? (ie. how high can it count to before rolling over)

2) This is meant to be a continuously running exerpiment so at some point my buffer is going to be full. From reading the documentation I want a circular buffer (I think this is chosen by default when you set the buffer to continuous read, is that correct?), and I'm going to want to dump information from the buffer into a data file (a .txt file or something) periodically. What's the best way to do this? Am I going to cause any software slow downs while doing this? I want the detection to still be running as I'm dumping data from the buffer to the file.

Thanks,
Chris
0 Kudos
Message 5 of 9
(7,409 Views)
Hello Chris,K

1) There is another way to do this that won't require another counter. Thanks to Kevin Price and his post here!

"I've discovered that DAQmx provides a neat way to do this in software. There's a DAQmx property node (probably a channel property node, but I can't verify from here) that allows you to query whether terminal count has been reached. When it returns a True, it resets so that subsequent calls return False until the next time TC is reached. As long as you query often enough, you'll be sure to notice all the overflows."

It is found in the channel property node under Counter Input >> General Properties >> More >> Terminal Count Reached
Thanks Kevin!

If this isn't suitable for your application, there are several way to hook up the output of one counter to the source of another. You can physically connect the two terminals, but usually you can make the route in software and not have to worry about doing any actual wiring 😄

The terminal count of a counter (how high it can count before it rolls over) is 2^(number of bits in the count register). The 6602 has 32 bit counters, so the terminal count is 2^32 = 4,294,967,296

2) You are correct that the driver will create and handle the circular buffer for you. The best way to handle file I/O, assuming that that your program runs long enough that you can't store all your data in memory, is to open/create a file and then put a write to file VI inside of the same while loop as your DAQmx Read. Then close the file after the acquisition. This will slow down how fast you read from the buffer, but not how fast you are acquiring data. If you have trouble overwriting the buffer, you can always try increasing the buffer size and/or increasing the number of samples to read when you execute the DAQmx Read. If you have enough memory to store all the data until the acquisition stops, you can always write all of the data after the acquisition.

An example of continuous file I/O can be found in the NI Example Finder or at this file path:
C:\Program Files\National Instruments\LabVIEW 7.1\examples\file\smplfile.llb\Write to Text File.vi

I hope this helps!
Eric
DE For Life!
0 Kudos
Message 6 of 9
(7,389 Views)

Hi, E. Lee,

Your picture is really helpful to understand how the counter works. I have a question for that. If there is no event coming in between two rising edges of the gate signal, what value will be written into the buffer? Because in my experiment, that situation happened and it seemed no data was recorded into the buffer. What could the problem be? Thank you.

Yongtao
0 Kudos
Message 7 of 9
(6,960 Views)
Yongtao,
 
This is almost certainly due to the (default) setting of the "Duplicate Count Prevention" property in DAQmx.   For a given board and DAQmx version, the property behaves consistently.  However, at various DAQmx versions, the default behavior has changed, and in some versions the behavior seemed opposite for different types of boards.  I personally have decided to quit trying to memorize the combinations because I support a few different LV installations with different hw and different driver versions which can't be arbitrarily upgraded due to company config control issues.   Anyway...
 
There are two types of behavior available when there are no source edges between consecutive gate edges:
1. do not add any value to the buffer for that interval, i.e., ignore gate edge
2. add a 0 to the buffer for that interval
 
The property can be found in the DAQmx palette, probably either a Channel property or Timing property -- I can't check from my network PC here.  It's a boolean so you can only choose True or False.  I always run a test case on the particular hardware & driver to see which setting behaves the way I want.  You could also simply query the property to find out what it is presently set to by default, then re-run with it set opposite.
 
If you were using traditional NI-DAQ, the default behavior would be to buffer up an indeterminate value.  As I recall, that value would often be a repeat of the value stored in the previous interval but it wasn't a guaranteed behavior.  So DAQmx is definitely the better choice.
 
-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.
0 Kudos
Message 8 of 9
(6,954 Views)

Hi, Kevin,

I changed that settings and it worked well. Thank you very much!

Yongtao

0 Kudos
Message 9 of 9
(6,950 Views)