ni.com is currently experiencing unexpected issues.
Some services may be unavailable at this time.
12-21-2011 01:51 PM
Hi everyone. I am having trouble getting a sychronized AO/AI loop running fast enough using a PCI-6115. I'm trying to do synchronized AO/AI with a where I collect a burst of around 6000 pts sampled at 2.5 MHz, do some calculations and then adjust the waveform for the AO for the next cycle. I would like to have this loop repeat as quickly as possible, ideally at <10 msec. If I used triggered AI or AO with finite samples, the loop takes around 15-30 msec per iteration, much longer than I would like. The time required to generate and read 6000 points at 2.5 MHz is only 2.4 msec. To achieve 25-30 msec, I programmed finite triggered AO and AI and use DAQmx Stop commands within the loop. This works fine, but is too slow. I understand the arguments that Windows isn't appropriate for trying to program high speed applications and LabivewRT on a separate target would be better. *But*, if I use Continuous Samples and a timed loop I can get 2-3 msec. Great! But when I try to change the waveform being written, the new waveform doesn't appear at the output for around 15 seconds. Presumably the continuous generation loads up the output buffer and it takes forever to finish writing. I need to have it write just the last waveform generated. I haven't figured out how to do this.
I've tried Continuous Samples for the AI and Finite Samples for the AO. In this case, I always get the -200288 error:
"Attempted to write a sample beyond the final sample generated. The generation has stopped, therefore the sample specified by the combination of position and offset will never be available.
Specify a position and offset which selects a sample up to, but not beyond, the final sample generated. The final sample generated can be determined by querying the total samples generated after a generation has stopped."
I have tried specifying the write relative to the first sample with an offset of zero, but that doesn't work either, same error.
Here are my specific questions:
1) What is the preferred approach for doing fast, synchronized AI/AO where you can change the AO data? Anyone have good example code?
2) Why am I getting the -200288 error? Isn't there a way within a loop to have the DAQmx Write write the data I just generated. I've tried wiring the beffer size to zero or 6000 pts, but neither work.
I'm attaching two files.
The first file is using a while loop and finite samples with DAQmx Stop within the loop. This works fine, but runs slow.
The second file uses a timed loop and and Continuous Samples for DAQmx Read and finite for DAQmx Write. This one runs fast (2-3 msec), but gets the -200288 error on the write. This is based on the Cont Acq&Graph Voltage-Int Clk-Timed Loop example. I added the AO generation and cycle time measurement.
Thanks in advance for any help you can provide!
Craig
12-22-2011 08:39 AM
Hello Craigp,
Regarding your first question, if you want to do fast and synchronized AI/AO my suggestion would be to use a Producer/Consumer Architecture for your code, this way even if it takes the computer a while to process the data you are gathering the acquisition will not stop because you have 2 different proccesses. You can find very useful code at the communnity.
Here are 2 examples that you can find very useful:
https://decibel.ni.com/content/docs/DOC-8962
https://decibel.ni.com/content/docs/DOC-2431
Why are you getting error -200288? here is a very helpful KB
http://digital.ni.com/public.nsf/allkb/BFCE83133C0ECAD786256E6000814B68?OpenDocument
Also in your synchronized finite generation and acquisition.vi change your write task, start the task before writing to the channel. Also it is recommended that you put the DAQmx start task.vi outside the while loop, and the DAQmx Stop Task.vi should be outside of the while loop as well. Otherwise what you are doing is starting and stopping the task on every iteration, this will make your code slower, it is as if you were using an Express VI.
I hope this was helpful!
Regards,
12-22-2011 09:55 AM
HI Miriam. Thanks so much for your answer. I've reviewed the Producer/Consumer examples, but I'm not sure I see how this architecture would be used for synchronized AO and AI. It seems like the producer/consumer architecture is used with one fast loop and one slow loop. But I need the AI to be reading a synchronized response to an excitation provided on the AO channel. So it seems like the AO and AI need to run in the same loop. Can you explain what you had in mind for how the Producer/Consumer architecture would work in my case?
I had also previously read the KB on the error -200288. It suggests that the error occurs because I need to add a DAQmx Stop task before the next Read step. So that's what I did in the working example I posted (the one that runs, but too slow).
I don't think I understand your suggestion about moving the start and stop commands outside the loop. If I do that I get the -200288 error again after the loop runs once. The KB you mentioned again suggests you need to execute the Stop before rearming with the Start. Is there some way to get it to auto arm without the Stop/Start?
Thanks in advance for any further help you can provide.
Craig
P.S. Feliz Navidad!
12-22-2011 12:45 PM
Hello Craigp,
What is exactly that you are doing to your input signal that you want to output afterwards? I need more information to tell give you more guidance. My idea for Producer/Consumer was that you read at top speed but analyze your data and output in the consumer loop, that way you don't miss any data. But in order to come up with a better solution I need more details regarding your application.
Thanks,
12-22-2011 01:03 PM
Hi Miriam. It's basically a feedback operation. In the final configuration, I have one AI channel and two AO channels. On the first AO channel, I provide an excitation signal (a sine wave) and I read the response of my system on the AI channel. I then do a simple calculation (<1 msec) on the data and calculate a value that is used by the other AO channel. Dropping data occasionally is not so important, but keeping the average speed of the loop high is and keeping the AI read synchronized to the AO on channel 1 is very important. So ideally I want an architecture where the Read/Write loop operate at high speeds and the AI is synchronized to the start of the AO waveform on channel 1. I am currently experimenting with a timed loop, continuous operation for AI and channel 1 AO, and then a separate loop for writing the AO on the channel 2. This looks promising as I have the continuous loop running as fast as the DAQmx Read will allow, ~2.4 msec/cycle. Now I'm working on how to optimize the speed of the 2nd loop such that it doesn't kill off the 1st loop and overrun the input buffer.
12-22-2011 01:18 PM
Craigp,
Have you seen the Multi-Function-Synch AI-AO.vi example on LabVIEW? You can find it on the LabVIEW Find Examples -> Hardware Input and Output -> DAQmx -> Synchronization -> Multi-Function->Multi-Function-Synch AI-AO.vi
Would this example help on the AI and the first AO. Also another question about the second AO, what is this signal? is it being feedback to somewhere else?
Regards,
12-22-2011 03:28 PM
Hi Miriam. Yes, I have seen this example. It is close to what I want to do, except in addition to what is shown I need one more AO channel where I can change the waveform written to the 2nd AO channel while the loop is running. In all the examples I've seen that use Continuous Samples, the generation is done once outside the loop. I need something where I can dynamically change the data that the AO Write is sending out.
12-23-2011 10:52 AM
Hi Miriam. Thanks for your help. I finally got this working the way I wanted with sufficient speed. Here were the keys:
1) Using two timed loops. The high priority one runs with continuous acquisition and generation.
2) I set the buffer size to the number of samples to read and the OverWrite property to "Overwrite Unread Samples."
3) I used a DAQmx Create Timing Source (Digital Edge Using Counter) wired to the timing input on the timed loop. I used the ai sample clock as the source of events and CTR0 as the counter.
4) I triggered the AI on Start Digital Edge using the ao start trigger and then started the DAQmx read outside the loop.
5) I put the DAQmx Write outside the timed loop and used DAQmx Start task outside the loop as well. When this starts, there is now a fixed phase relationship between the acquired and generated signals.
6) In the timed loop I have my calculation. It runs fast enough to keep up with the timed loop. Occasionally the timed loop runs long and some data is overwritten. That's ok for me because the replacement data is equivalent to the lost data in my case.
7) I have a separate timed loop using the Create Timing Source (1 kHz). It uses a local variable from the fast timed loop and writes it to another AO channel using DAQmx Write (Analog DBL 1Chan 1Sampl). A critical thing here was the keep autostart to off and start the write outside the loop.
So now I have synchronoized AO/AI and variable data being written to an AO channel with the the fast loop running at a speed limited only by the DAQ time and the slow loop running almost as fast. Yay!
Thanks again,
Craig
04-25-2012 09:49 PM
Hi Craig,
Would you please share your final VI since it was such a tricky task and wonderfully finished piece of work.
Thanks,
Yan