....How do I make
> the output occur for instance during the 33ms time of waiting on the
> next frame ? Thanks.
Being able to do this will be affected by how your diagram is written,
but more importantly by how the 1394 transfer takes place -- how much
CPU time is left while the transfer takes place.
The first thing to do is to write your diagram so that there isn't a
dataflow dependency between them. There are multiple ways of doing
this, so I think I'll describe two.
If your data is stored in a big array, the best solution is probably to
use shift registers to do two things at once in one loop. Your loop
will have a top section that does the acquisition and outputs the data
to the right hand side to a shift register. The left hand shift
register will go into the bottom section of the loop where the
processing and output occur. This coding trick is similar to loop
unrolling and/or pilelining, and the only downside is that you need to
prime the loop and process the remainder. Use i or an initial value in
the shift register to avoid doing something bad on the first iteration,
before data from the acquisition has made it to the bottom section of
the loop. And, when the loop terminates, you need to arrange for the
last image acquired to be processed either outside the loop, or run the
loop an extra iteration.
This implementation is a bit complicated, but without making excessive
copies of your image, you are now doing acquisition and
processing/outputting in parallel.
A second approach that is simpler to write will be to use parallel loops
and a bounded queue. Make two parallel loops that are both fed a queue
refnum. One loop will acquire the image and put it on the queue. The
second loop will read from the queue and process/output the image. If
you know that the acquisition will take longer, you probably don't need
to worry about bounding the queue, but you can use this to your
advantage to pace the two loops. The reader of a queue will always
sleep when it reads from an empty queue. When something is placed on
the queue it wakes up and gets to work. For a bounded queue, the writer
sleeps when there is no room to put another element. You can use this
to make sure that the loops stay as synchronized as you like. You can
also use semaphores if you want additional synchronization.
The queue implementation will work quite well and be easier to read, but
it is copying around the image. If the image is an IMAQ Vision image,
then that is simply a reference and this implementation works great. If
your image is several megabytes in an array, the overhead of the queue
copies may be overwhelming.
Other variations of this could use globals or LV2 style functional
globals, but they have some of the same copying issues and even less
synchronization built in.
Once your diagram expresses the parallelism, the driver doing the
acquisition will now be the key piece. If it consumes the CPU for 33
ms, then the parallel diagram won't be of any benefit. The tasks will
be in parallel, but a 33ms atomic acquisition will effectively kill all
of the benefits of this diagram. Hopefully the I/O is handled by
controller chips or the driver sleeps rather than busy looping.
Another thing you might need to do is to make sure that LV has threads
enabled, set from Tools>>Options on the Execution page. And you may
find it necessary to allocate more threads for the standard execution
system. There is a tool in vi.lib/utility/threadcfg.vi that will show
you how many OS threads each execution system has and allow you to
change them. Since you have all of your work going on in one VI, the
top and bottom part of the loop will both be in the same execution
system, and you would like to have two threads if the driver is
consuming one. Change the thread allocation to two and if the driver
gods are smiling, you should get the parallelism you need/want.
By the way, I think there was a presentation on doing this with NI IMAQ
boards at NIWeek 2001. You might want to browse the slides. The
presenter would have been Jeff Kellam I think.
Greg McKaskle