Showing results for

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Mute
- Printer Friendly Page

kmeador

Member

06-15-2004 01:50 PM

Options

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report to a Moderator

Jeremy_C

Member

06-17-2004 09:15 AM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report to a Moderator

id not answer your question or if you have additional questions.

Calculate Frequency

Kevin_Price

Proven Zealot

06-17-2004 01:14 PM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report to a Moderator

The first key concept is to be prepared to store multiple cycles of your waveform in the output buffer. The best # will depend on your waveform frequency and your output update rate.

For example, suppose you have an update rate of 100 kHz and you want to produce a 6 kHz output waveform. Theoretically, one cycle of your output waveform lasts for 100/6 = 16.6666... update periods. Since you can only generate integer #'s of updates, the solution in this case is to define an output buffer containing 3 cycles of your waveform. This will last for 3*100/6 = 50.0000 update periods. Bingo!

Now let's consider the general real world case instead of a convenient example that works out perfectly. You need to determine how to fit

This is mathematically equivalent to a problem in rational approximation. Specifically, you will be trying to determine the most appropriate choice of N and D to most closely approximate the fractional ratio between f_o and f_w. In other words,

The prior link outlines an algorithm that gives a successive approximation, i.e., each iteration provides an N and D that get progressively closer to the true fraction.

In the real world, there's a practical buffer size limit on how large you want to allow

In my past job, I had to perform this approximation in real-time and wanted very consistent execution time. So my solution is based on having solved the problem for 1, 2, and 3 terms in closed form. Even for the very worst case of approximating sqrt(2) (as outlined in the link), the approximation is good to 1% using only 3 terms. In other words, the theoretical time required to define D cycles of the waveform would be N update periods, with an error no greater than 1% of an update period.

I'll post my subvi if I'm able, but I may need to password-protect the diagram. If I recall correctly, the inputs provide user options for minimum requested accuracy and maximum allowed N, and there are outputs for N, D, and a boolean to tell whether the accuracy request was satisfied.

-Kevin P.

Matt Pickard

Member

06-18-2004 10:35 AM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report to a Moderator

That sounds like a neat example. If you are able to post it, you can upload it Example Code Library:

http://www.ni.com/devzone/dev_exchange/ex_search.htm

Matt P.

Applications Engineer

National Instruments

Kevin_Price

Proven Zealot

06-18-2004 11:16 AM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report to a Moderator

I tried it out last night for a wider range of inputs than I originally needed to accomodate, and found a few that didn't work out correctly. I had made the subvi more universal than it strictly needed to be, but had primarily tested it for a fairly restricted subset of inputs.

I'll try to rewrite it as an iterative algorithm, as mentioned in my first posting. That way I could post it for sure.

-Kevin P.

Kevin_Price

Proven Zealot

06-22-2004 03:14 PM - last edited on 08-19-2019 08:09 PM by pcerda

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report to a Moderator

I did a little more google-searching and found a couple newsgroup postings that were even more useful than the original link. The articles are embedded in the diagram of the two implementations given below.

User-controlled inputs are:

1) original floating point value

2) requested max error

3) max allowed value for numerator

4) max allowed value for denominator

Outputs are:

1) floating point value of rational approximation

2) numerator of rational approximation

3) denominator of rational approximation

4) actual error

5) boolean flag telling whether error spec was met

6) # of terms / iterations to achieve approximation

The first (and recommended) implementation is based on a continued fraction repr

esentation of the original floating point value. In my testing, the slowest execution time was about ~5x the fastest.

I left several array indicators on the front panel that helps show the progression of the approximation through all its iterations. So you can check out successive approximations for pi or something.

The second implementation is based on iterating through a sequence of "Farey" fractions. It's fastest case can be several times faster than the continued fraction method, but there are other cases that slow it down by a factor of 1000+. (It seems to be worst when the floating point value is very close to an integer, a situation that may arise fairly often.) Because of its virtually unbounded execution time, I advise **against** using it. Consider its inclusion here to be solely for educational purposes.

As suggested earlier in the thread, I'll post the continued fraction version as a piece of example code.

-Kevin P.

- Tags:
- AO_Num_Samples
- DAQ_AO

Kevin_Price

Proven Zealot

09-27-2018 07:23 PM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report to a Moderator

After recently linking to this thread, I noticed that I could no longer download the example vi using Chrome. I decided to repost, and in the process I did a little bit of minor tweaking as well as making a wrapper that helps translate from the terminology of rational approximation with its talk of numerators and denominators over to the terminology of DAQmx with its talk of buffer sizes and # of waveform cycles.

In the process, I also wound up upcompiling the code to LV 2016. FYI.

-Kevin P

Bob_Schor

Knight of NI

09-27-2018 08:43 PM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report to a Moderator

More than 30 years ago, before the era of PCs, when 65kB was as much memory as you could address directly, I programmed a "sum of sines" algorithm for a behavior stimulus that covered a frequency range of 0.02 - 1 Hz. The technique we used was to generate a waveform of 16,384 points that represented the 7th, 13th, 23rd, ... (all relatively prime harmonics, either 8 or 10 of them) played back so that the fundamental ranged from 0.001 to 0.01Hz (some of these number might not be quite right -- it's been a long time). The point is you need to have a buffer large enough to have an integer number of periods inside it. If it is a single frequency, you need one period's worth of points.

Bob Schor

Kevin_Price

Proven Zealot

11-03-2018 09:52 PM

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report to a Moderator

And yet another update. The topic came up again, I pointed here, and in the process realized that the wrapper utility I posted recently didn't have any terminal connections. I added those and then added yet another layer to demo how to connect it to an actual AO sine wave generation task. The zip below contains both the vi's posted above (after I added wiring terminal connections to one) plus a vi that integrates them with an AO task.

-Kevin P