From 11:00 PM CST Friday, Feb 14th - 6:30 PM CST Saturday, Feb 15th, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

Improving efficiency of complex I/O operation with 2 loops (and error 200284)

Hi,
 
I'm attempting to write a sine wave output to an actuator on a rig, and check that the displacement is as desired for a range of frequencies, along with measuring the force at each frequency.
I need to run 10 wavelengths at each frequency over which to average the force reading, but I want to monitor the displacement as often as possible (i.e. every wavelength)
 
To start with I built a simple DAQmx VI which I hoped would output one wavelength to the rig, and read back the displacement simultaneously. I have attached this VI as "Custom MX I-O v2.vi". It is here that I get the error 200284 - 'Some or all of the samples requested have not yet been acquired'. I've tried to follow the suggestions to fix it but using a longer read timeout doesnt appear to make any difference; I dont want to increase the sample rate because I want it linked to the output; I dont have any triggering; and I dont know how to make it read later in the program.
 
Anyway, assuming this can be solved fairly easily by someone with more knowledge than myself, I would also like some advice on where to add the loops to alter the frequency, and alter the displacement at each frequency.
I have attached my proposed solution as as "Custom MX I-O v3.vi" but I can see that it will not be particularly efficient as the task will have to be created and deleted for each iteration. If anybody could tell me a neat way to get around this I would be very grateful.
 
On a side note, is it possible to find out what state a task is in at each position (i.e. Unverified, Verified, Reserved, Committed, or Running) - I couldn't find a property node which would do this.
 
Many thanks for any assistance you can give,
 
Ian Haigh
 
p.s. I was trying to a certain extent to copy the example of Synchronized Analog Input/Output from http://zone.ni.com/devzone/cda/tut/p/id/4322
Download All
0 Kudos
Message 1 of 10
(3,679 Views)
Hi Ian,
 
The reason why you were getting that error is because you had the input task timing set to use the output sample clock (dev1/ao/SampleClock), but did not do anything to force the input task to start before the output task. Since both tasks were set to generate/acquire the same number of samples, if the output task started first, it would finish first and stop its sample clock. This would cause the input task to timeout (error 200284) at the Read VI since it didn't get enough clock cycles to finish inputting all its samples. I've written an example VI to show you how I force the input task to start before the output task by wiring the error cluster to the input task first. Since the input task uses the output sample clock, it will wait for the output task to start its sample clock before acquiring data. This is a basic synchronization technique by itself.
 
If you want to acquire samples from multiple wavelengths of the same frequency, can you just increase the number of samples to be generated/acquired (and not change the sample rate)? 
 
I do not know of any way to check what state a task is in.  DAQmx is optimized so that you should not have to mess around with the states for most cases.  If you want to learn more, The NI-DAQmx Help (Key NI-DAQmx Concepts -> Tasks -> Task State Model) has a lot of information concerning the task state model.
 
Let me know if you have any other questions.
 
Way S.
NI UK Applications Engineer
Message 2 of 10
(3,663 Views)

Hi Way,

Thanks for that info - I'd been wondering why the example on http://zone.ni.com/devzone/cda/tut/p/id/4322 had wired the error cluster that way!

I want to find the amplitude and phase of each wavelength individually, and then take averages of these values. I suppose I could do as you say, and then split up the array afterwards, but I also want to change the amplitude of the output wave if the displacement being measured is not correct and so I want to do this as often as possible i.e. every wavelength.

From my interim report regarding the program:

" At low frequencies the amplitude of the input wave is set and the hydraulic actuator will respond appropriately. However, as the frequency increases, the amount of time for the apparatus to travel from the maximum to the minimum value will decrease. By simple physics, this increases the speed that the actuator will have to move. Eventually the limit of the equipment will be reached and to keep at the higher frequencies, the amplitude will decrease.

For the testing of tyres this is not a good thing as the displacement should be kept constant throughout each test. For this reason, a displacement control loop is being programmed which examines the displacement signal from the rig and compares it to a specified target set by the user in order to keep the two as close as possible. The recommended displacement target is 2mm as this ensures that the equipment should not reach the extent of its capacity, even at the higher frequencies being tested."

Btw, is it possible for you to save the VI you posted as an earlier version - I'm running 7.1 so I can't open the file.

Also, I don't have access to the rig for the next week due to the easter break so my next response may be a bit delayed while I test a few things out.

Many thanks again for your help,

Ian

0 Kudos
Message 3 of 10
(3,653 Views)

Hi Ian,

Here's the VI again in LV 7.1.  If you need to adjust the amplitude for every wavelength, you will have to stop the generation session and change the amplitude. So you could add another for loop within the main loop for wavelength iterations like you did in your other VI (custom MX I-O v3.vi). 

Let me know if you need any more help.

Way

 

0 Kudos
Message 4 of 10
(3,637 Views)

Thanks a lot Way - that's brilliant!

With a minor tweak to specify the input terminal configuration and the maximum and minimum values for the AI Voltage Create Channel it works a treat 🙂

There is a couple more things I'm struggling with - I'm trying to persevere but I'm guessing somebody on the forums might know a neat way of doing these to save me some time...

Whereas previously I was specifying 'Sampling Rate (Hz)' and 'Samples to acquire' which were fed directly into the sample clock, I actually want the user to specify the number of samples per wavelength, and number of wavelengths per frequency increment so I get the same number of samples taken for each frequency:

100 samples per wavelength * n wavelengths per second (Hz) = 100n samples per second (the sampling rate to be input to the sample clock)

100n samples per second * 10 wavelengths per frequency increment = 1000n samples per frequency increment (the number of samples to be input to the sample clock)

The trouble is that the value of n is found inside the loop (labled as 'Current Frequency') and I need to use it before the loop begins - almost a catch 22 situation! I'm sure there must be a way round it by being clever with the data flow order as the value itself is not needed before it is produced... I tried wiring directly but that produced errors. In the version I have attached I also tried using a local variable, but this takes the last value left in memory (15Hz) for the first iteration before the value of n is calculated. If anyone has any suggestions I would be most grateful.

On a separate topic, I thought of a way around the displacement loop issue: if I could design a loop (or more likely 2 nested loops) that produced the output 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 etc. then perhaps I could use this to control the frequency. It seemed like a really simple thing to produce but I cant seem to get my brain around it!

Many thanks as always,

Ian

Message Edited by ianhaigh on 04-12-2007 02:54 PM

0 Kudos
Message 5 of 10
(3,621 Views)
Well I managed to solve the 2nd problem on my own - I've attached the VI in case anyone wants to see how simple it actually was and how dense I was being! 🙂
 
The first problem is still niggling tho...
 
Ian
0 Kudos
Message 6 of 10
(3,610 Views)

Well this is what I've come up with as a possible solution to the first problem, but I havent quite executed it properly...

The trouble is that loop#1 (see lables on the block diagram) executes fully and only feeds the last value into loop#2 which then executes the specified number of times, but with 15Hz frequency every time.

How would I go about structuring it so loop#1 exectues once and feeds the current frequency (5Hz) into loop #2. Then when this has finished executing, prompt loop#1 to iterate to get 6Hz etc.

Cheers,

Ian

0 Kudos
Message 7 of 10
(3,606 Views)
Hi Ian,
 
I think you're straying in the wrong direction with your last VI.  What you need to do is to move your DAQmx Timing VIs inside of your loop in ForceDataflow Desired Inputs.vi.   That way, you can use Current Frequency as an input to change the DAQmx Timing VI settings every frequency increment within the loop.  You will also have to rewire the error clusters accordingly.
 
Let me know if that helps or if you have any questions!
 
Way
0 Kudos
Message 8 of 10
(3,599 Views)

Hi Way,

Thanks so much for helping me out on this project - that final step you suggested was pretty simple in the end. I've attached the final VI I came up with in case you (or anyone else) is interested.

The way its been designed there are 2 ways to specify the number of wavelengths per frequency increment:

a) input 10 wavelengths once and find the average amplitude and phase for these 10 as a group
b) input 1 wavelength 10 times, find the amplitude and phase for each wavelength and take the average of these

...or alternatively you could do a combination of these i.e. the average of 5 wavelengths 5 times

Cheers again,

Ian

0 Kudos
Message 9 of 10
(3,576 Views)

Hi Ian,

I'm glad I could help.  It looks you've gotten the hang of forcing dataflow with error cluster wiring.  Your code is quite neat and I like the way you add comments to different parts of your code as it makes it a lot easier to read. 

There are ways to make your code even more faster/efficient in the future if you're interested.  Generally, you'd like to separate your data acquisition from your data processing into different sections, especially in the case of when you need to run your acquisitions at higher speeds (ie. your next acquisition step does not have to wait for the previous data processing step to finish). An easy way to do this is to acquire all your data first, then process that data at the end by extracting the relevant data from your waveform array.  A more advanced method would be to acquire and process your data concurrently, by using queues to separate your data acquisition from your data processing into different concurrently running loops. These advanced architectures are covered in our LabVIEW Intermediate course, and you can find more information here:

http://digital.ni.com/worldwide/uk.nsf/web/all/B46DC4E8B94DF74480256E4E005202BC

Good luck with your project!

Way S.

0 Kudos
Message 10 of 10
(3,561 Views)