LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Synchronizing analog output and input for imaging

Solved!
Go to solution

Hi all,

 

I'm stuck in my graduate project and really need some help. I'm testing a laser scanning imaging system, where we use two MEMS mirrors to scan the sample and use a photomultiplier tube (PMT) to acquire the voltage signals and translate them into images.

 

I use the same DAQ board for both analog output and input. The DAQ board sends X and Y functions to the MEMS mirrors so that the 2D scanning pattern starts from left to right and from top to bottom.

Scanning rate: 131500 pixels/second.

Dimension: 1170 pixels per row, 514 rows in total.

So, the mirror will scan 601,380 pixels per image, which takes about 4.57 seconds to finish. I've pretty much finished this part in LABVIEW.

 

However, only part of the scanned pixels are read by the PMT. We want to get a 512 x 512 pixels image. So the PMT works like this:

1) The sampling rate is also 131500.

2) Skip the first row.

3) Starting from the second row, the PMT will skip the first 329 pixels, read in the next 512 pixels, and skip the rest 329 pixels again. Then, it moves on to the next row.

4) Skip the last row.

 

My approach in the flat sequence

1) Skip the first 841 signals (1170 - 329 = 841).

2) Create a for loop, execute 512 times.

3) In each loop, first skip 658 signals (329 x 2), then read the next 512 signals.

4) Wait the rest 1499 pixels to finish scanning (1170 + 329).

 

Problem

The mirror and the PMT parts should start and finish executing at the exact same time. However, when I run my VI for analog input and create the image on panel, it takes about 5.7 seconds to finish, which means they are not synchronizing at all. It seems that some unexpected time is spent in the for loop, but I don't know how to change the code to meet the timing requirement.

 

Please see the attached VI. Any help is greatly appreciated. 

 

~Sheng

0 Kudos
Message 1 of 23
(4,759 Views)

You have a misunderstanding of what happens in LabVIEW.

 

Look at this pic, from your code:

Snip 1.PNG

 

That wait is about 6.39 mSec (841000/131500).  You can't wait for a fraction of a mSec, using that function.  It will wait for 6.  The coercion dot tells you that it's converting a DBL into an INT.  But the accuracy of that is questionable - the first mSec is always dubious on a WAIT.  It could be 5,5 - 6 mSec.

 

QUESTION: Which one occurs first - the wait for 6.39 mSec, or the TICK COUNT (mSEC) at the top?

 

If you answer anything except "I don't know", then you're wrong.

LabVIEW is perfectly free to schedule the TICK COUNT before, during, or after the WAIT, since you didn't specify which you wanted first.

 

That means that your TIME LAPSE number is bogus - you don't really know when it started.

 

If you were to do this instead:

Snip 2.PNG

Then you guarantee that the TIME LAPSE measurement occurs AFTER the wait is over.

 

There might be other things wrong, but I see those right off the bat.

 

 

Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


LinkedIn

Blog for (mostly LabVIEW) programmers: Tips And Tricks

0 Kudos
Message 2 of 23
(4,718 Views)

Looking at your main loop:

 

StartStop.PNG

 

You are STARTING and STOPPING a task in the loop.  That is never a good idea - the overhead for doing the start/stop is unpredictable.

 

If you're trying to precisely time the data collection, then give it a clock rate and let the hardware time it for you (Plenty of examples for doing that in the EXAMPLES FINDER).  Set up the task with a given rate and # samples, START the task, wait for it to finish, collect the data, and CLEAR the task.

 

And again, you're trying to wait for 5.003 mSec (658000 / 131500).  It's going to round that down to 5, not a big difference.  But that's 5 mSec ADDED to whatever it takes to START the task, Acquire a sample, STOP the task, and replace the data in the array.

 

So it may not be doing what you think it's doing.

 

BTW, your idea to allocate an array beforehand, and then REPLACE parts of it as you go is a good one.

 

Your idea to display the Column number as you go (within the loop) is not - that takes time, as well.

 

Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


LinkedIn

Blog for (mostly LabVIEW) programmers: Tips And Tricks

0 Kudos
Message 3 of 23
(4,709 Views)
Solution
Accepted by Pandatrice

My approach in the flat sequence

1) Skip the first 841 signals (1170 - 329 = 841).

2) Create a for loop, execute 512 times.

3) In each loop, first skip 658 signals (329 x 2), then read the next 512 signals.

4) Wait the rest 1499 pixels to finish scanning (1170 + 329).

 

Consider this: add up all those pixels, both the ones you want to record, and the ones you want to skip.

 

If I read you right that would be:

841 + 512 * (658 + 512) + 1499

 

Whatever that number is, set up a task for that many samples, and record the whole bloody thing.  Let the hardware time it for you.

 

Then, AFTER the data is in hand, go thru and throw away the first 841 points, and then for each loop, throw away 658 and keep 512... etc.

 

IOW, let the HARDWARE do what hardware does best: precise timing.  

Let the SOFTWARE do what software does best: weird logic.

Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


LinkedIn

Blog for (mostly LabVIEW) programmers: Tips And Tricks

Message 4 of 23
(4,700 Views)

Thank you so much Steve! I learned a lot from your replies. Your idea of reading all the data first then keeping only 512 x 512 pixels works perfectly. You saved my project, thank you 🙂

0 Kudos
Message 5 of 23
(4,545 Views)

You saved my project,

 

Great!  I'll expect the royalty checks any day now...:manlol:

 

P.S. Consider posting your solution here, so somebody searching this topic can benefit.

Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


LinkedIn

Blog for (mostly LabVIEW) programmers: Tips And Tricks

0 Kudos
Message 6 of 23
(4,535 Views)

Ok, so what I did was just transforming the recorded 514 x 1170 2D array into 512 x 512 2D array. I don't need to worry the timing anymore as long as the data generation and collection tasks are triggered at the same time.

0 Kudos
Message 7 of 23
(4,525 Views)

as long as the data generation and collection tasks are triggered at the same time.

 

I don't know if your situation requires it, but if you need to INSURE that they both happen at the same time (within a few nSec), you can use signal routing to do it.

 

MIDAQ-mx  | Advanced | Signal Routing.

Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


LinkedIn

Blog for (mostly LabVIEW) programmers: Tips And Tricks

0 Kudos
Message 8 of 23
(4,511 Views)

It seems that there's no way I can check whether the data generation and collection tasks happen at the exact same time using my current VI, so I tried to add the DAQmx connect and disconnect terminals into it.

 

Please see my current VI, where I have combined the analog output (to generate X and Y functions for the scanning mirror), a clock pulse train (for triggering), and the analog input.

 

If I understand it correctly, I should remove the property node "DAQmx Channel", add and choose "DevP/PFI9" as the destination terminal in DAQmx connect terminal VI, and "DevP/ctr1" as the source terminal. However, "DevP/ctr1" is not in the list of the available terminals and I don't know why. I'm using NI PCI-6115 together with BNC-2110.

 

I started learning LabVIEW as I started this project, please correct me if there's anything wrong. It's so frustrating that no one else in my lab knows LabVIEW well. I want to make sure my code is correct before I start testing it on the delicate MEMS mirror and real samples..

 

Thank you for your time.

0 Kudos
Message 9 of 23
(4,290 Views)

In case you may want to know, the X and Y files are provided by the MEMS company. They are both csv files containing 601380 data points. X is like a sine function and Y is like a step function. They look good in my oscilloscope.

0 Kudos
Message 10 of 23
(4,283 Views)