Cool, I've been <i>waiting</i> for someone to ask this question b/c I
put together a fairly nifty solution to it when I faced the same
problem.  Assuming, that is, that you're making an output buffer
representing a waveform with one particular frequency and then doing a
continuous output that cycles through that buffer multiple times.
(You would be resetting and reprogramming your board to generate a
waveform representing a different frequency.)  Sound right so far?

  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 <b>D</b> full cycles of your frequency <b>f_w</b> waveform
optimally into <b>N</b> of your output update periods which cycle at
frequency <b>f_o</b>.  In other words, you're trying to satisfy:

   <b>D * (1/f_w) ~= N * (1/f_o)</b>

  This is mathematically equivalent to a problem in <a
href="http://www.mathworks.com/access/helpdesk/help/techdoc/ref/rat.html";>rational
approximation</a>.  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,

   <b>(N / D) ~= (f_0 / f_w)</b>

  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 <b>N</b> to become.  That could be one way to
decide when to terminate the approximation.  Another way could be
based on the percent error between your approximation and the true
fraction.

  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.

Reply via email to