Counter/Timer

cancel
Showing results for 
Search instead for 
Did you mean: 

Conceptual problem in using a PCI-6602?

Hi, All You Wild and Crazy NI/LabVIEW Types --

 

I have a problem that's been close to sending me off the deep end for more than a month now, and I think that I'm so enmeshed in it that I can't see the forest for the trees anymore. I'd like to apologize in advance for the length of this post, but there are some details that might or might not be important, and I'd rather make the mistake of giving you too much information than not enough.

 

We do impact-cratering experiments, using a gun to launch (usually) spherical projectiles at a variety of targets. One of our big efforts is to measure the velocities at which material is ejected from growing craters. We do that with a line-generating laser, oriented so the "sheet" of laser light is perpendicular to the target's surface and through the impact point; we strobe the laser at a programmed rate (with our PCI-6259 board) and take a time exposure of the scene with a Nikon D100 DSLR. When target material -- usually grains of sand -- is ejected, the laser illuminates a "slice" through the curtain of ejecta, illuminating a small portion of the fragments numerous times in their trajectories. Since we know the scale of the photograph and its orientation relative to the laser's illumination, and we also know the rate at which the laser is flashing, we can easily calculate the velocities of the illuminated particles. I'm attaching a picture (file 4044, cropped.jpg) of an example taken with an older camera to give you an idea. In the picture, the laser's illuminating the scene from the right of the frame and the projectile flew into the picture from the top of the frame, traveling along the left-hand edge. The brightest portion is the flash from the impact, and the rest of the parabolic trajectories are the grains of sand in flight. The target bucket, full of coarse sand, is the elliptical looking cylinder at the bottom of the picture. It's roughly 28 cm in outside diameter, if you'd like a scale.

 

As you might imagine, with our projectiles moving anywhere between 0.7 and 3 km/s, sequencing everything is pretty important. We're using (or trying to use) LabVIEW to do all of the sequencing, instrument control, and data storage. Things are going pretty well so far, except for what I'll describe in more detail below. A couple more things, though, first. It's important that we measure the projectile's speed in each shot, as that controls impact energy and momentum, which are critical to know in a given experiment. We do that with simple laser-photodetector pairs (which we normally call "velocity stations") arranged along the projectile's trajectory. As the projectile passes between a laser and its detector, its shadow is detected and a TTL pulse is sent to our PCI-6602 board. Depending on the experiment, we use three or four such laser-dector pairs. They use counters 0, 1, 2, and 3. We know the distances between the laser stations and, once we get the times between detections, it's s simple matter to calculate the projectile's velocity.

 

We also use LabVIEW to fire the gun, and we do that because opening the camera's shutter has to be synchronized with the firing pulse, which currently is sent via P1.1 on the 6259. Here's the problem: when we test the laser-detector arrays in a "standalone" mode (that is, without any other tasks or operations being done with LabVIEW), they work infallibly. It's when we try to use LabVIEW to fire the gun that we get either very erratic results from the velocity stations/6602 or no results at all.

 

I've tried a range of things, from starting the two-edge measurement task before the firing signal is sent, to trying to force things with a timed sequence, to doing things with brute force via a seuqence structure. When I try to start the two-edge measurement task first, though, the firing signal isn't sent until the counters time out. This of course, wrecks the experiment, because all of the timing is then messed up. The VI that I've attached (Version 1.vi) is a HIGHLY simplified version of the initial attempt I made at doing this, with all sorts of background stuff removed just so I can cut to the chase. (Only one two-edge measurement task is shown, for instance.)  I think that the VI is pretty self-explanatory (and embarrassingly primitive), so it probably doesn't need much in the way of explanation. Counter 7 and PFI 0 on the 6602 are used to accept the signal from the firing button and trigger the event structure, which contains the two-edge separation and gun-firing tasks. (In reality, I use a separate VI to have three to four concurrent two-edge separation tasks running concurrently, one for each velocity station.) I start the two-edge separation tasks first so the detectors and counters are ready for the projectile. It's not necessary here, but I kept the 500 ms wait frame in this example because that's why the sequence structure exists -- to allow the shutter of the Nikon to open completely before the gun fires. After those 500 ms, the firing signal is sent to the circuit that actually fires the gun.

 

What happens in this configuration is that the second frame of the sequence structure doesn't execute until the 5-s timeout transpires in the two-edge separation task. I've also tried this using a line on the 6602 to fire the gun instead of P0.1 on the 6259, but that ends up with the same result. (Both counters are used on the 6259 to strobe the main illumination laser, so they're unavailable, if you're wondering. In any case, we need four counters for the four velocity stations.)

 

FINALLY, my question: What am I doing wrong, here? If I put the two-edge separation tasks in the same frame of the sequence structure as the firing task, the gun fires when it's supposed to, but we get no velocity measurements. I've also tried to force the timing with another version of a sequence structure; I'm attaching another very simplified version below as Fire and speed example.vi.

 

After you recover from your violent fits of laughter, I'd really appreciate hearing what you might recommend. (And no, surrender isn't an option.)

 

Thanks for taking all of your valuable time to read this huge post -- I really appreciate it!

 

Mark

Download All
0 Kudos
Message 1 of 11
(7,108 Views)

I'll try to take a look when I get a chance, but would need you to backsave to LV 2010 and repost.

 

-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 11
(7,095 Views)

Thanks, Kevin -- Here are those files in LV 2010 format, if I did this right...

 

Mark

Download All
0 Kudos
Message 3 of 11
(7,075 Views)

Hmmmm.  Very limited time, but here's a couple thoughts:

 

1.   I'd sequence the 2-edge measurement & the DO firing differently.  I'd create and start the 2-edge task before entering the sequence structure, and defer the 2-edge *reading* until *after* firing the DO.  (I'd also be sure to return the DO to a False state before clearing its task). 

 

2.  Not quite sure what the purpose & rationale is for relying on the DAQmx Signal Event to help with timing & sync.  Seems likely there's a better way to sync the tasks themselves through timing signals.  Is there a specific reason you did it that way, or was that just where you happened to end up after trying a bunch of different stuff?

 

3.  In general, it's a good idea to do all your task config outside any loops so you can be more responsive inside 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 4 of 11
(7,069 Views)

Hi, Kevin --

 

Sorry for the long delay in replying.  We have a visiting scientist in our lab this week, and we're being run ragged (in a good way!).  Let me see if I understand your points correctly.  (I'm just a government-issue scientist, not a programmer or an EE, so please bear with me, here.)

 

(1)  I'll try resequencing the DO and two-edge measurement early next week when we're closer to being back to normal.  Your suggestion gives me hope, which I kinda need about now!

 

(2)  There are two reasons I'm using the signal event in this VI: (a)  Not being a LabVIEW guru, it's something I found that I'm able to understand with some degree of confidence and, at the same time, have it work for us.  (We have another gun with a firing sequence using the signal event setup, and it works flawlessly.); and (b) For safety and procedural reasons, everybody has to leave the laboratory when we fire the gun.  Firing it is done with a mechanical firing button, which is part of a safety-interlocked electrical circuit.  The signal from the firing button is what I've been using to trigger the event structure.  When you mention timing signals in this regard, are you referring to a timed structure?  I have tried using a timed structure (again inside the event structure), but I get the same lousy results that I described in my original post.

 

(3)  When you say "outside any loops," are you referring to the fact that I have the DO and two-edge separation tasks completely inside the event structure and thus inside the while loop?

 

Thanks a million for your time, Sir!

 

Mark

0 Kudos
Message 5 of 11
(7,049 Views)

I agree with all 3 of Kevin's points.  His first suggestion will probably fix your problem (see below).  The 2nd and 3rd suggestion would improve efficiency and responsiveness, but #2 might not be possible since independently triggering four outputs in hardware would require the use of 4 counters (on the 6602 anyway) which might be busy doing other tasks in your application (although if you don't need the stations to trigger independently then you could implement this with a single counter).

 

 

I think I have an explanation of the problematic behavior you are seeing based off of the following bits of information from your post:

 

1.  Running the small example code by itself works flawlessly, but adding other simultaneous functionality fails.  You mentioned you are doing this on 4 stations, so I'm assuming 4 counter input tasks running in parallel.

2.  The behavior you are seeing is that the 2nd sequence does not execute until after the read times out (note that the sequence is supposed to be executing in parallel with the read).

 

It sounds like the problem is coming from a combination of calling into DAQmx Read before data is available (this consumes one of the threads that LabVIEW has allocated to your application until DAQmx Read finishes executing) along with the fact that LabVIEW allocates 4 threads per execution system per priority by default.  Since all of your threads (from what I can tell) are executing on the same priority, the 4 reads you are calling will block anything else from executing until they have completed.  By then it's too late and the firing of your gun happens after the counter task has already timed out.

 

You *may* increase the number of threads allocated to your application by using a VI that is included with LabVIEW (vi.lib\Utility\sysinfo.llb\threadconfig.vi) and this would also probably remedy the behavior you are seeing.  However, rather than throwing more threads at this application I think the better solution would be to change the sequencing of your tasks like Kevin suggested ("create and start the 2-edge task before entering the sequence structure, and defer the 2-edge *reading* until *after* firing the DO")--in doing this you would now expect to see data immediately upon calling DAQmx Read and you avoid the situation where Read is blocking indefinitely and consuming an application thread.  You could take this a step further by checking the Available Samples per Channel property (or using the DAQmx EveryNSamplesAcquiredIntoBuffer event) to ensure that data is actually available before calling Read.

 

 

Best Regards,

John Passiak
0 Kudos
Message 6 of 11
(7,026 Views)

Hi, John!

 

Thanks for your suggestions and explanations.  I'm trying to work through everything that you said, there, and I have a question or three. 

 

I attached a VI to my original post called Fire and speed example.vi that (I think) does what you and Kevin are talking about, in that the two-edge task is started before the DO executes and then reads after the digital signal is sent.  Is that in fact what you guys mean, or am I misunderstanding something?

 

What exactly are the "timing signals" that Kevin mentions?  Timed structures or something else?

 

Regarding Kevin's item (3): when you talk about configuring the tasks outside of loops to improve responsiveness, is that referring in this case to the fact that they're configured inside the WHILE loop containing the event structure, inside the event structure (not a loop), or something else?

 

Thanks again --

 

Mark

0 Kudos
Message 7 of 11
(7,005 Views)

Hi Mark,

 

I'm glad you asked.

 

Fire and speed example.vi doesn't start the task explicitly.  Actually, even if starting the task explicitly, the value returned is going to be the first measurement taken after the read is called for an on-demand task (I don't really like this behavior for the record but it's not something that can be changed now).  So, you'll end up having to do something like this:

 

Two Edge Separation.png

 

Using implicit timing means that the sample will be latched in to a buffer upon completion and so when you read you will just pull the sample from this buffer rather than trying to initiate the measurement with your read call.  On the digital output task, be aware that the value of the output line remains high after the above code executes--I'm not sure when you intend to turn off the output but be sure to know that clearing the task does not change the line state.

 

 

What I would assume that Kevin meant by timing signals was that you can use hardware timing to achieve your goal rather than relying on software.  If you wanted to you could use your external trigger directly to trigger a counter output rather than use the signal to generate a software event which in turn writes a value to the output line.  The caveat I mentioned earlier is that independent triggering of 4 stations would require 4 counters (but then again, you are currently using a counter just to generate the interrupt so this same caveat applies to your current program as well).

 

 

It doesn't matter where you put the configuration exactly, but rather that the configuration is not run more often than necessary.  Putting configuration inside a loop that runs repeatedly is inefficient if the configuration does not have to occur more than once.  For example, in my above snippet you could call the read function multiple times in a loop without having to reconfigure and start the entire task repeatedly (the task will run until you stop or clear it).

 

 

Best Regards,

John Passiak
0 Kudos
Message 8 of 11
(6,999 Views)

Hi, John --

 

Sorry for the long delay in replying, but we finally got a chance to test things.  I tried your setup of the CI and DO tasks but had problems initially.  We're using four counters on the 6602 to get our redundant speed measurements with four separate CI tasks, and I was getting an error about unavailable DMA channels.  After doing a lot of reading, I explicitly set up the Data Transfer Mechanism for each of those CI tasks to use interrupts instead of DMA.  That did the trick, so thanks again and again!!

 

The fact that it works with this (PCI-based) system, though, begs the question as to why I don't have to do anything like this to have the speed measurements work on our PXI-based system that's running a different gun.  That setup is like the original Version 1.vi that I posted (except for the fact that there are four CI Two-Edge Separation tasks started before the sequence structure instead of just one as in my example).  The CI tasks start and *don't* timeout before the DO executes to fire the gun, *plus* all four tasks are using DMA channels somehow.  At least I'm assuming that, since I'm not using the Channel Property Node to force them to use interrupts.  It's worked flawlessly (I'm knocking on wood) with that system for over a year now, but all of a sudden I don't know why that should be.

 

Thanks again -- that's one huge pain in the neck I don't have to worry about any more!*

 

Mark

 

* There's a Spanish (I think) proverb that's pretty applicable here; something like "What was bitter to live through is sweet to recall."  I guess you guys get a lot of that...

0 Kudos
Message 9 of 11
(6,977 Views)

DMA vs interrupts is normally only an issue for buffered measurement (and generation) tasks.  Your example didn't call DAQmx Timing.vi to set up a buffered task, so I'm kinda surprised you got the error.  Maybe it's something unique about the two-edge separation task, because I never ran into it for non-buffered tasks but I also rarely did two-edge separation measurements.

 

You didn't add a call to DAQmx Timing.vi in the config chain, did you?

 

The only other thing I would speculate might relate to the DMA / interrupts issue is the hw-timed single pt task you constructed for ctr7, seemingly just to generate a app-level event?   I don't honestly know for sure, but perhaps setting

up hardware timing at all, even if only for a single point rather than a buffered measurement, may try to reserve one of the DMA channels?  

 

I'm hoping you've found a way to eliminate all that event stuff entirely and simply use PFI0 as a timing signal for your other tasks.   If I understand your app right, I'd configure all the two-edge velocity measurement tasks to use PFI0 as an arm-start trigger, explicitly start them, and then read them *after* generating the digital Dev2/port1/line1 pulse.  I assume you've hardwired from Dev2/p1.1 to Dev1/PFI0?   (Another option might be to generate a single firing pulse with a Dev2 counter.  You could then specify that counter's output as the arm start trigger with no external hardwiring at all.  All the signal routing will be done automatically with no screwdriver work by DAQmx.  Assuming, that is, that you have a RTSI cable between the boards.)

 

-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 10 of 11
(6,973 Views)