Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

synchronized digital output and delay triggered analog input

Hello,

I am using a PCI-6221 board to do synchronized digital output and analog input.  I need to output digital pulses on two lines and then obtain analog data after a specified delay. These two tasks need to be accurately synchronized, because this process is extremely time-sensitive. I have written a LabView program which does this. I am using a counter's internal output as the sample clock signal for both the analog input and the digital output, as this was the only way to provide the same clock signal to both tasks. I tried several other methods, for example using the 10 MHz timebase for both sample clocks, but the frequency of this clock was unsupported by the analog input. I also tried using the timebase for the Sample Clock for the digital output, and then the do/SampleClock for the analog task, but this also returned an error. The internal counter timing, on the other hand, works fine. 

For the trigger, I am using the other counter's internal output. The counter is set to "ticks" output, and the delay is specified at the counter (I did this because the startTrigger.Delay property on the analog input task was conflicting with the sample clock for some reason). 

My problem is this: When I run the program, it works fine for a delay of less than 300 ticks and analog input samples of less than 300. When I try to increase these numbers to above this range, the program hangs up. This is a problem, because I need both of these numbers to be higher than these values. Confusingly, if I run the counter trigger and analog input task as a separate VI, using a hardware timebase as the sample clock, I get no such limitations on the delay and samples to be obtained. It is only when I use the counter output as the sample clock that this problem occurred. I tried separating the trigger counter and analog input as a separate VI, with sample clock as a control, and calling it from my main VI, but this caused the same problem I described above. This indicates to me that the problem I am having is due to the specific sample clock I am using. However, I cannot change this because it is the only method I have found that synchronizes the digital output and analog input. 

I have attached a screen shot of the program I have written. Any help in resolving this problem would be greatly appreciated.

Thanks!

0 Kudos
Message 1 of 15
(4,487 Views)

robo1,


Would it be possible for you to post your code?  I think that would help me troubleshoot a little better.

 

Regards,
Dustin D

0 Kudos
Message 2 of 15
(4,453 Views)

I only had a couple minutes here to figure out your description & screenshot, and am pretty sure I'm not solid on all the details.  However, I *do* notice that your tasks aren't fully sync'ed via dataflow.  The upper two tasks seem to be sequenced properly to each other (DO task auto-starts on DAQmx Write prior to starting the counter task which acts as its sample clock).  And the lower two tasks seem to be sequenced properly to each other (AI task is started prior to the counter task which acts as its trigger.)   But I see nothing to enforce the relative sequencing of the upper pair to the lower pair.

 

Another thing I noticed is that most of your tasks are being cleared right after you start them.  You need to wait for them to finish the job you configured them to do.  Only the AI task has an implicit wait time built in to collect the specified # of samples.  The others are getting cut off at the knees.

 

-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 15
(4,424 Views)

Hello,

Thanks for the replies.

Dustin, I have attached the code. I hope this helps.

Kevin, how do I ensure proper sequencing of tasks? I looked at some related examples, especially a synchronized analog output and digital output, and tried to replicate their structure, but I didn't have any success. The problem is I don't fully understand how to sequence the tasks and where to connect them, so if you could help that would be great. In regards to clearing them, should I insert a loop that checks "Is Task Done" every iteration?

Thanks again for the help.

0 Kudos
Message 4 of 15
(4,386 Views)

Hi robo1,

 

Here is a suggestion on how to start your tasks in the correct order and have them run continuously:

SS-2010-04-06_13.50.22.png

Notice your counter task that is running the clock is started last.  This way all of the other task that are dependant on the counter, will wait for that counter to start then immediately react as they will all be on the same sample clock.  This code will end either when the task finishes, which probably won't happen since you have that counter set to run continuously, or when the stop button is pressed.  Post back if you have questions!

 

Have a great day!

Dustin D

Message 5 of 15
(4,370 Views)

Dustin beat me to it with a nice illustration of the sequencing and pausing you need.  Should be a good head start.

 

One thing worth noting: I generally try to code as though I'm allergic to sequence structures and global variables.  But Dustin's use of a simple 2-frame sequence here is much neater and clearer than what I would have done.  I generally route my error clusters up and down among my DAQ tasks, thus using simple dataflow to enforce my sequences.   But it's quite a bit more messy to look at and detracts from code readability.  I'm gonna have to rethink some of my "code snobbery" about the sequence structure for cases like these.

 

[Note: there are other considerations too.  WIth a sequence structure as Dustin illustrated, all the DAQ tasks maintain separate, independent error statuses (stati?).   The way I have generally routed error wires up and down, I have a single shared error status for all DAQ tasks.   Each has its pros and cons, depending on the app.]

 

-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 6 of 15
(4,364 Views)

I prefer a slight modification to Dustin's approach.  As a rule, I try to never use sequence structures.  However, this is the one case for which I make exceptions.  By starting each of the tasks before the sequence structure (save, obviously, the counter task) this allows me to maintain parallelism for as long as possible.  Since starting a DAQmx task is one of the more resource intensive actions, keeping the operations parallelized can result in a noticeable increase in performance.  Thus, I do something like the following:

 

Capture.PNG

Message Edited by Seth B. on 04-06-2010 02:38 PM
Seth B.
Principal Test Engineer | National Instruments
Certified LabVIEW Architect
Certified TestStand Architect
Message 7 of 15
(4,360 Views)

Hello again.

Dustin, I modified my code to include the structures you suggested (using Seth's idea for the sequence structure), but now the program encounters an error when it is reading the analog input. It gives an error message saying "some or all of the requested samples have not been collected yet", but I know I am providing a signal to the physical channel I specified. Right now I have each task's error signals completely independent, ie I do not wire error clusters between tasks. This is the only other change I made to my code besides adding the sequence structure and while loop, so I am wondering if I need to use error flow as well to ensure proper functioning?

Also, I would like this program to stop after the specified samples have been collected so that I can automatically re-run the entire program at a later time. To make it stop automatically, I inserted a "Is Task Done?" VI in the analog input task and wired the output to the stop condition of the while loop. Will this stop execution after the samples are collected without interfering with proper execution? It didn't seem like this was the cause of the problem I described above, because I got the same error when I removed this feature and left the while loop identical to Dustin's.

Thanks for the help.

0 Kudos
Message 8 of 15
(4,296 Views)

Hi militem,

 

The error you are receiving usually means
that you are trying to read more samples from the buffer than have been
taken.  So basically your sample rate is too low for the number of
samples you are reading, or the number of samples being read is too high
for your sample rate, depending on how you would like to look at it.

 

Since
your counter task is being used as your sample clock you will definately want to know when that task finishes.  That should signal the end of your aquistion.  You may also want to want to delay reading the buffer until after it is done and then read a specific amount of samples from the buffer.

 

I hope this helps!
Dustin D

0 Kudos
Message 9 of 15
(4,242 Views)

Hello Dustin,

With regards to the sampling, I have run the program with the maximum possible sample rate (5e6) and with 1 sample to optain, and it still returns the same error. So I am not really sure what is going on, but it seems that the problem is in the code. The original program, that I posted about the first time, acquired up to 300 or 400 samples without problem, but since making the sequencing changes, it has returned error 200284 every time. 

With regards to the loop termination, I'm not sure I completely understand what you are saying. Do you think I should not terminate based on the analog input task and wait for the counter task to finish? The problem with that is that the counter task does not have a specified end time, but I need to be able to re-run this entire program repeatedly. Is there another way to do this?

Also, how do I read the buffer after all the samples have been acquired?

Thanks again for your help.

 

0 Kudos
Message 10 of 15
(4,229 Views)