Counter/Timer

cancel
Showing results for 
Search instead for 
Did you mean: 

Photon Counting, Time Stamping, and basic help with how DAQmx works

Hi,

Thanks to anyone who can give me help. I've done some LabView programming with a DAC before in an older version of LabView, I'm just starting out with Counter/Timer applications with the new LabView and I'm trying to figure out what's going on. Information on exactly what's going on is hard to come by. I've spent the last two days going through most of the LabView help files and examples, and today I've been going through this forum. I'm hoping though that someone can provide me with an explanation as to what's going on.

My application: I'm trying to make an application that will provide highly accurate time stamps (using the 80MHz internal clock ~12.5ns) in a quantum key distribution experiment. What happens is I generate a photon pair, this pair then goes through an optical circuit and eventually each gets detected by a separate photon detector which outputs TTL pulses, these pulses are then meant to come into the counter and be stamped with a highly accurate event time, so two lists will be generated and a time correlation function will then be run on these lists to determine the paired events in each list.

My Hardware: PCI6602 counter/timer card, BNC-2121 board, LabView 7.1

My general idea of what I have to do: Have 2 counters running off of the 80MHz timebase to keep an accurate time, have an overflow counter so that when the counters reach their maximum they reset to zero and the overflow counter gets incremented (so that the experiment can run for longer then the size of the counters), have the 2 photon detector signals come in as the gates for the two counter channels, write a time stamp to a file every time the gates fire.

(I've included the code I have so far)
Steps I have so far:
1) Create a channel
- I've tried various things now to put a gate or a trigger in, Start Trigger complains about not having the right component, arm trigger seems to work but from what I've gathered from reading other posts I want a DAQmx Timing.vi to use as the Gate (using a Timing vi as the gate was not at all obvious to me), so how do I use the timing VI as a gate? Can you explain to me what each pin is doing and what's going on? I can look at example code easily enough myself, but I want to have an idea of what the heck is happening.
2) Start a task
3) Read the counter
- Alright so if I get the gate working, someone also told me that I have to use a buffered read so that the hardward continues to read the clock and there's no software latency issues, I'm going through the example Counter Digital Events-Buffered Continuous.vi again, but if someone can help me on what to do, and more importanly how things are working and why I'm doing things that would be great
- I also need a write function here to write time stamps to a file, anything I need to be aware of so that the write doesn't slow down the time stamping or anything else?
4) Stop Task
5) Clear Task
I need to keep all this going in some sort of loop as well until the end of the experiment, thoughts?

What does the DAQmx trigger.vi do? Because that's what I've been trying for the longest time to use and it hasn't been working.

As you can see I have two loops there, I was trying to make the vi continuous so that it could receive multiple events from the photon detectors, but what I've done is probably very ugly, is there a better way to set this up?

Lastly, if there are any good resources which EXPLAIN what components are doing and how to use them (I've gone through the help files on all the DAQmx components and they don't have much in depth info), I'm more then willing to do some work and learn how to do things myself, all I need are some good resources.

Thanks to anyone that can help me with this gigantic post, I really appreciate it 🙂
Chris
Message 1 of 51
(11,574 Views)
Chris,

Have you worked through the suggestions offered by E. Lee in this thread yet? I'll try to help also after I can look at your code later today.

I think one key concept to emphasize is the "Start Trigger." In the above thread, it sounded like you expected it to cause a trigger and initiate your measurement. In fact, it must be called before starting the DAQmx task. It doesn't generate a trigger; instead, it describes where to look for the signal that will act as a start trigger.

It sounded to me like the purpose of the start trigger is just to make sure the timestamps of the 2 channels are in sync. If so, you could configure the counter to watch for a start trigger signal at one of the digital output pins. So your program could first set that bit False, then configure both measurements to look for a rising edge there, then start the counter measurement tasks, and finally write a True bit to create the rising edge trigger signal.

Re: counter overflow with 80 MHz source. See E. Lee's suggestion in other thread. If you don't have 2 hw counters to spare, 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.

-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 2 of 51
(11,522 Views)
Chris,

I took your vi and made up an example for a single channel of timestamping. There's one main vi for performing the timestamping and another one that generates simulated photon pulses to be timestamped. It worked on my lab PC with a 6602, but note that all the default values assume that the 6602 is Device 2. Here are some notes in no particular order:

1. The timestamper is setup to start on a digital trigger. In this example program, that digital trigger is a real hardware signal that's generated by a Digital Output task when you select the "Trigger Now" button.

2. This is a buffered task so every photon pulse will get timestamped.

3. I chose to illustrate 2 different concepts that can help to keep your Data Acq loop responsive even while doing file writing. The first concept is not to simply request a bunch of samples from DAQmx Read. Instead, I first query to find out how many samples are available. I only read and process them after they're sure to be available. This way the Data Acq loop doesn't freeze up for a second or two while waiting for DAQmx Read to retrieve data.
The second concept is to send the data off to an independent loop for processing (graphing, calculations, file writing, etc.). Here, I wrote the timestamp data and rollover information to a queue. A separate loop reads from the queue and performs all the real work on the data. If file writes start bogging down, all the timestamp data just builds up in the queue for a while.

4. The example isn't complete. I put in text comments about the kinds of things you'd need to add. Such as the actual file writing. Also, a little bit of processing to handle the rollover cleanly.

5. Note that I purposely chose to use doubles for the timestamps -- this will allow you to store larger values than a u32 after accounting for the # of rollovers.

6. The vi that simulates photon pulses is just a pulse train generator. Note that you can update the frequency on the fly. Each time you change the freq value, the actual pulse train will also change freq without stopping.

7. Eventually you want to do this with 8 channels? Be aware that there are only 3 DMA "pipelines" available for handling fast photon pulses. The other 5 would need to be explicitly configured to do their data transfers with interrupts. If your detectors are firing "fast" (a few kHz or more), you probably won't be able to keep up. The exact capability is system (and program) dependent, but it is definitely a limitation.
One possible workaround is to get 2 more 6602's because each card gives you 3 DMA "pipelines".

Good luck!

-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 3 of 51
(11,503 Views)
Thanks for all the help Kevin, I'm going through the code and ideas you sent now. Quick questions about the 8 channels because I wasn't aware that while there's 8 counters on the board, there's only 3 DMA channels to route signals around fast. So two things, I'd be interested to see how to program the other 5 counters with interrupts because while the pulses are fast 25ns, I'm not sure how frequently they'll be coming in, it might only be a couple of kHz. Any example code around that I can look at? But more likely they'll be faster, so is there any way that I can interleave signals on the 3 DMA channels? ie. can I continuously switch back and forth between which counter gets the DMA pipeline? Or is this going to cause lots of software latency issues? Because while I'm using the 8 counters, they're really going to be two groups of four counters and only one counter at a time in each group of 4 should be firing. Is there other inputs on the 6602 that I could use to read the channel information quickly? ie. If I just used two counters, one for each group of 4, and then used the 3rd channel or some other input lines on the card to read in which of the 8 counters fired I'd have the same result.

Thanks again for the help,
Chris
0 Kudos
Message 4 of 51
(11,496 Views)
Hi Kevin,

I found out a bit more about the DMA issue you mentioned. A better question then what I asked before is can different counters share the same DMA channel? As I mention before, it's actually 2 groups of 4 counters, and only 1 counter per group of 4 fires at a time. So can each group of 4 counters share 1 DMA channel? Then I just require 2 DMA channels? The raw rate that the counters should be firing at is a couple of MHz (like 1-10MHz) so hopefully it's not a problem to do something like this.

Thanks,
Chris
0 Kudos
Message 5 of 51
(11,486 Views)
Hi Kevin (or whoever else wants to jump in and help)

Thanks for that example code that you sent me. I've been playing around with it and understand it pretty well now. Here's what I want to do next, I want to scale your code, ie. yours handles one counter, now I want to handle 2 then up to 8. So I've tried to make the read portion of your code a subVI which I can include in another VI. Then I just instance this subVI 8 times. Sounds simple but I've gotten muddled up. I have a bunch of code zipped up.
- SingleTimeStamping_v2.vi - The original code (Kevin's code).
- SingeTimeStamping_v3.vi - I separated just the read code, it's not a subVI yet, I was just doubling checking that everything still worked when I separated it. I plan to make the code which writes to a txt file a subVI as well when I get there, which is why I took that code out.
- SingleTimeStamping_v4.vi - Alright, now I took a shot at turning this thing into a subVI that I can then import into another VI. What I'm looking for is to encapsulate the reading of one channel within one subVI icon. There's a lot of parameters that are common to all the channels. I think the queue doesn't like something. But I should be able to have a queue input shouldn't I? I want to stick timestamps from all 8 counters onto 1 queue, that should be possible? If so, what am I doing wrong?
- CompleteTimeStamping_v1.vi - My shot at using two of these single time stamping units in a VI. I try and share the queue between them. But something does not like my setup, I get a GPIB must be the controller error.
- Simulated Photon Pulses.vi - pulse train generator to simulate photon pulses.

Alright, so there's the strong possibility that I have set this up completely wrong (though it currently makes sense to me). What I want is this:
- a subVI that takes care of reading one channel, has all the necessary parameter connections, and can stick timestamps onto a queue.
- a subVI that takes this queue of events (from eventually 8 counters) and writes them to a file. (I should be able to handle this one alright myself)
- an overall VI that implements 8 of these channel subVIs, one of these write subVIs, sets up a queue, and all the other bookkeeping.

Issues:
- how do I wire up a stop button for this whole thing?
- the queue, from your original code it was fine to branch the queue into 2 different loops, I don't think my code likes this?

Thanks for any help,
Chris
0 Kudos
Message 6 of 51
(11,469 Views)
Hi Chris,

If you intend to have several of these subVIs to control multiple counters, you can make use of a Stop control in your main VI, and pass the control reference of the Stop button into your subVI in order to register its events the way you have set up now. To create a reference for a control, right click on the control and select Create >> Reference.

Your inquiry regarding sharing a queue in multiple subVIs will probably be better answered in the LabVIEW discussion forum. Try posting here.

With regards to the DMA inquiry, the PCI-6602 device has 3 DMA channels that will allow you to have 3 counter operations. The remaining counter operations will use interrupts instead. You shouldn't need to explicitly configure the data transfer mechanism, as the driver should take care of it. Below is an article further describing this:



Thanks,
Lesley Y.
0 Kudos
Message 7 of 51
(11,460 Views)
Hi Lesly,

Thanks for the suggestions. I created a control reference for my stop button in my main VI. In my subVI I figured out how to created a boolean ref and hooked it up to the connector pain. Inside my while loop in my subVI I have an event structure that checks whether my ref has changed, will this check whether the value of what I'm referencing has changed? ie. will it pick up the event of my stop button changing? I then use a property node to get the value from the reference and stop the while loop. So that all looks good. But when I try and hook up the control reference to the subVI it complains about the wire types. I've looked at 4 examples of reference passing and as far as I can tell I've done exactly the same thing. Any ideas what's going wrong?

Regarding the DMA issue. I have 8 counters grouped into 2 groups of four, only 1 counter will fire from each group at a time. So at max, there will be 2 counters firing at once. Is the driver smart enough to share the 3 DMA channels among the 8 counters? ie. so if 2 counters fire will the driver send the info along 2 of the DMA channels? Or does the driver assign counter 1 to DMA1, counter 2 to DMA2, counter 3 to DMA3, and everything else to interupts? Because as long as it's smart I should have any problems.

Thanks,
Chris
0 Kudos
Message 8 of 51
(11,448 Views)
Hi Chris,

With regardPlease refer to the LabVIEW shipping example, "Dynamically Register for Events" to register your stop button events.

If at any time, only two counter tasks will be running, then they should both use DMA for data transfer. Either way, unless you need specific channels to use DMA (e.g. they measure the higher frequencies), you will not have to worry about explicitly setting data transfer modes. The default mode will be to use the DMA, and when there's no DMA available, the driver will use the interrupt instead.

Also, I looked into your previous queue question more, and there should be no problem with the different subVIs accessing one queue. You can used a named queue to avoid having to pass wires around.

Thanks,
Lesley
0 Kudos
Message 9 of 51
(11,438 Views)
Hi Chris,

A correction to my previous posting regarding DMA assignment. The article refers to the Traditional driver only. You will need to configure counters to use interrupt instead of DMA where necessary. You mentioned you will be using 8 counters grouped into 2 groups of 4..I'm not sure I understand that. Are all 8 counters performing event counting or different operations, and are they taking turn running?

Thanks,
Lesley Y.
0 Kudos
Message 10 of 51
(11,410 Views)