LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Waveform with precise frequency - modified on the fly

I would like to continuously output a waveform with a variable but
precise frequency. To me it seems that in order to achieve precise
control over the frequency of the waveform one needs to change the
buffer size (see for example the thread "How do I determine the
appropriate buffer size to use to generate a particular frequency
waveform?"). How do I do this on the fly, i.e. while the waveform is
generated? I tried the "AO Buffer Config.vi" together with the "AO
write.vi" while the waveform is being created, but the result looks
correct only for the initial buffer size used. If anyone has a good
example how to properly use those or has a different solution I
would really appreciate it.

Thanks,

Tim

PS:
Some specs: RT-Card PCI-7041 with 6040E
output frequency approx.15kHz
Does anyone know what accuracy of the frequency I can achieve for this frequency range?
0 Kudos
Message 1 of 9
(3,838 Views)
See the attached vi. Basically, instead of changing your waveform, you change the sampling rate that it is output. The buffer remains the same size, and as long as the sampling rate is high enough, the waveform is pretty accurate.

As for your other question. The default timebase is a 20 MHz signal. This limits some, but you should be able to generate many different frequencies.

For example, to get precisely 15 kHz, the number of cycles must be 3 and the samples per cycle must be a mulitiple of 10. I will leave this as the default.
Randall Pursley
0 Kudos
Message 2 of 9
(3,825 Views)
Thanks Randall,
unfortunately I am currently using Labview 7.0. But changing the
sampling rate was not my problem, that is something I can achieve
easily - however this limits the precision with which you can
actually set the frequency. By adjusting the buffer size which holds
a certain number of cycles (in addition to choosing the right
sampling rate first) I think one can do much better than this. What
I need is a very precise control over the output frequency if
possible better than 0.1 Hz. Maybe this is not possible with the
card I am currently using?

Thanks for your reply,

Tim
0 Kudos
Message 3 of 9
(3,817 Views)
Here is a copy of the vi in 7.0.

Your precision is still defined by the timebase either way you do it. This way works without having to reallocate buffers, which you would have to do and I don't think it can be done on the fly.

You can easily get resolution less than .1 Hz this way. If I set the desired freq as 15 kHz and set the Samples to 480 and cycles to 9, everything works pretty well. The sampling clock rate is then to 800 kHz. If you increment this 1 Hz at a time you get a small increment in the frequency.
Randall Pursley
0 Kudos
Message 4 of 9
(3,814 Views)
Hi Randall,

thanks for posting the 7.0 version - however it seems that the 6040E
card does not support NI-DAQmx, so I was once more unable to test
your VI. Instead of setting the sample clock rate (800kHz?!) I would
rather directly set the output frequency. With which card did you
test this vi?

Any other suggestions?

Thanks,

Tim
0 Kudos
Message 5 of 9
(3,814 Views)
It appears that is what I have too, although it comes up in MAX at PCI-MIO-16E-4, and mine does support DAQmx (NI-DAQ 7.4.1)

As for the sampling clock. I am not setting it, I set the parameters for the buffer and it is computed. I just adjust the buffer parameters to make sure that the sampling rate that is computed is a realizable one.

Message Edited by rpursley8 on 05-11-2005 04:28 PM

Randall Pursley
0 Kudos
Message 6 of 9
(3,806 Views)
Tim,

I'm glad to see that old posting of mine (...appropriate buffer size...) got some use! It sounds like your app is tougher than mine though b/c you need to change the waveform freq on the fly.

As far as I know, the buffer size cannot be manipulated while a task is running. So changing the output rate does sound like the way to go. The advantage is that the waveform frequency changes instantly. Unfortunately, the frequency precision is limited (as stated earlier in the thread) by the 20 MHz timebase.

Consider the example given -- 800 kHz update rate so that 480 sample points produces exactly 9 cycles of a 15.000 kHz waveform. Well, that 800 kHz update rate is created by dividing the 20 MHz clock down by 25. The next closest achievable discrete output rates are made by dividing by either 24 or 26, i.e., 833.33 kHz or 769.23 kHz. This in turn would change your waveform from 15.000 kHz to 15.625 kHz or 14.423 kHz. Not very precise.

I'm inclined to think that you may need to perform a non-regenerating output and then continually write to the output buffer on the fly. For example, I'd start by creating a larger-than-strictly-necessary output buffer. Then I like to imagine the buffer as though divided into 1/3's. I start by writing enough data to fill 2/3 of the buffer. Thereafter, each time the actual output reaches a 1/3 buffer size point, I write an additional 1/3 buffer of data.

Now let's further suppose that the entire buffer represents about 3 seconds worth of output or 2.4 Mega-samples. (This is a tradeoff between how fast the actual waveform output freq responds to requested changes, the amount of CPU consumed monitoring and feeding the output buffer, and the memory and CPU required to generate chunks of waveform data). So each write to the buffer should represent about 1 second. Let's also suppose that every write to the buffer must start from a positive 0 crossing and contain an integer number of waveform cycles. At the moment I'm imagining a pure sine wave for simplicity.

So if we start with the 800 kHz update rate and 15.000 kHz waveform, then we want to deal with chunks of about 800 kilo-samples. But since we also need some multiple of 480 samples, let's pick the multiple 1667. This makes 800.160 kilo-samples or 15003 cycles of the waveform. Write these twice for a total of 1600.320 kilo-samples in the buffer, then start the task.

Now we poll the output properties until about 800 kilo-samples (1/3 the buffer) have been written. Then we write an additional 1/3 buffer chunk (presently 800.160 kilo-samples). Etc. Note that you'll need to be a little fancier than this to make sure you're always filling in the 1/3 of the buffer that starts about 1/3 buffer size ahead of the current output position. With the numbers given, the 160 sample per chunk discrepancy would eventually cause a problem.

At some point, the user or program decides that a new waveform frequency of 13.710 kHz is needed. Still using the 800 kHz update rate, I come up with a ratio of ~128 waveform cycles per 7469 samples. (The actual waveform freq will then be 13.710001 kHz). I'll again need a multiple that comes near to 800 kilo-samples, and I come up with 107. So I generate an array of 107*7469 = 799.183 kilo-samples representing 13696 cycles of the waveform, and write it to the output buffer. I keep writing this chunk approx once per second until another waveform freq change is needed.

That's the basic idea. With this approach, the data written to the buffer ranges from 1-2 seconds ahead of the actual output DAC. So if you request a change in waveform freq, there'll be a delay before seeing it at the output.

In summary: output rate change gives you instant response but fairly poor frequency precision. Buffer writing on the fly gives you excellent frequency precision, but a significantly delayed response plus a lot of memory, CPU, and bookkeeping to deal with.

-Kevin P.
CAUTION! New LabVIEW adopters -- it's too late for me, but you *can* save yourself. The new subscription policy for LabVIEW puts NI's hand in your wallet for the rest of your working life. Are you sure you're *that* dedicated to LabVIEW? (Summary of my reasons in this post, part of a voluminous thread of mostly complaints starting here).
Message 7 of 9
(3,775 Views)
Hi Kevin,
thanks a lot for the excellent reply - it really helped a
lot. Unfortunately my application does not allow for such a long
delay. On the other hand the precision one can achieve by changing
the output rate is also not enough, so I guess I have to come up
with a different solution. Any ideas are welcome.

Best regards and thanks again,

Tim
0 Kudos
Message 8 of 9
(3,774 Views)
Hi T_M-

Kevin's suggestions are excellent- unfortunately there must be a tradeoff somewhere to ensure both frequency accuracy and continuity in your output.

Please let us know if you find a crafty way to speed up operation. Good luck!

Regards,
Tom W
National Instruments
0 Kudos
Message 9 of 9
(3,749 Views)