LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Generate 2 sine waves, different period, same # of samples

Solved!
Go to solution

LabVIEW 2015 (backward compatibility for older Windows OS).

USB-6212 DAQ (using both analog out channels)

 

I have a VI that monitors a number of inputs, and so far has been generating a single sine wave on AO0.

Now I have to update it to generate a sine wave on AO0 and a second sine wave on AO1.

I am using the DAQMx Write VI (Analog 1D wfm, N Chan, N Samp).

Now when I create the task, I set it up to use Dev1/AO0:1) so I can output to both channels simultaneously.

When the user sets the desired sine wave period (30 - 120 beats per minute; 0.5 - 2.0 Hz), I calculate the frequency (Hz) and amplitude.  I also set the number of samples so that the end of one sine wave crosses zero at exactly the point in time of the starting zero of the next sine wave to prevent a 'jump' between the waves.  No problem.

 

However, with 2 outputs, I have to set the number of samples the same for both waveforms or I get an error (-200103) when I call the DAQMx Write.

 

If  the user selects the same BPM, it all works well.

 

I'm hoping there is either a solution to the Write error with different number of samples, or a quick way to calculate the smallest integer that satisfies both sine waves (integer number of samples in each sine wave so they both start and end at zero.

 

Thoughts?

0 Kudos
Message 1 of 27
(4,807 Views)

Is zero padding one of the waveforms to the length of the longer waveform an option?




Certified LabVIEW Architect
Unless otherwise stated, all code snippets and examples provided
by me are "as is", and are free to use and modify without attribution.
0 Kudos
Message 2 of 27
(4,803 Views)

Hi Michael,

 

Thank you for the thought.

No, padding with zeroes doesn't work.  I'm driving 2 electric coils with the sine waves, and they have to keep going at the requested frequency, stopping (zero) and restarting doesn't work.

 

Thanks,

Jeff

0 Kudos
Message 3 of 27
(4,795 Views)

If the output is continuous, you could try generating the sine waves with Sine Wave.vi (in the Signal Processing->Sig Generation palette). It will maintain the phase of the generated sine wave, so you shouldn't have any jumps in the waveform.

sine_wave.png




Certified LabVIEW Architect
Unless otherwise stated, all code snippets and examples provided
by me are "as is", and are free to use and modify without attribution.
0 Kudos
Message 4 of 27
(4,788 Views)

Generate sinusoids using a much higher sampling frequency.  The USB-6212 can generate AO at 250k Samples/sec.  Let's make the math simpler and set a sampling rate of 100 kHz.  As long as the sinusoids you are trying to generate are relatively "low frequency" compared to this carrier (for example, less than 1 kHz), you'll be generating a cycle with at least 100 points, which gives a pretty good approximation.  LabVIEW has routines to generate sinusoids, so you could just pair them to generate the waveforms and then output them at the carrier frequency.  Problem solved.

 

Bob Schor

0 Kudos
Message 5 of 27
(4,781 Views)

 

I'm using Sine Waveform.vi from the Waveform Generation palette.

It looks a little different than the icon you're showing, but I haven't found that particular VI.

Is that version newer than LV 2015?

 

Either way, I tell the sine wave generator how many samples to generate, and that works out.

The tough part is I have 2 separate waveform generators, and they both have to be continuous.

 

If the user selects 60 bpm, that's 1 cycle per second, at 1000 samples per second, that's 1000 samples to output to the AO0 channel.  I can set that up using Sine Waveform.vi.

 

If the user selects 90 bpm for the second motor, that's 1.5 cycles per second, or 0.66667 seconds per cycle.  At 1000 samples per second, that's 667 samples per wave.  I can set that up using Sine Waveform.vi, and if it is the only motor, that works just fine.

 

When I try to write the 2 analog outs, at the same time, I can't seem to get the Analog Write VI to accept 2 different 'length' waves.  The 1000 samples continuous to AO0 and the 667 samples to AO1, generates the errror.

 

I'm hoping I'm missing something obvious.

 

Thanks for the reply.

Jeff

 

0 Kudos
Message 6 of 27
(4,781 Views)

What you're missing isn't exactly obvious.  But it also isn't terribly complicated.  The key idea is that you'll need to iterate in a loop that keeps feeding "a little more" of your pair of sine waves to the task in each iteration.  The sine wave generation functions have both inputs and outputs for phase, so you just need to feed in last iteration's phase output as this iteration's phase input.

 

In fact, there's a shipping example (at least in LV 2016) named "Voltage (non-regeneration) - Continuous Output.vi" that will already give you a proof-of-concept for generating 2 distinct sine waves with different frequencies in one AO task.  You just need to designate both physical channels in a manner like "Dev1/ao0:1" (which means the *range* of ao channels starting at ao0 and ending at ao1, all on device "Dev1").

 

 

-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 27
(4,767 Views)

We'll use your example of a carrier at 1 kHz.  If you generate a 1 Hz wave for 1 second (1000 points), you'll output exactly 1 cycle, right?  If you generate a 1.5 Hz wave for 1 second (1000 points), you'll output 1.5 cycles (i.e one and a half sinusoids).  The "trick" is what you do for the second set of 1000 samples -- for both channels, you continue generating "where you left off".  On Channel 0, the 1 Hz channel, it's just another sinusoid, but on Channel 1, where you've already generated 1.5 sinusoids, you generate the second half-sine and one more (another 1.5 sinusoids, but shifted in phase).  The net result is in two seconds, channel 0 has output 2 sinusoids while channel 1 has output 3, just what you wanted, no breaks smooth all the way.

 

But what if you wanted a sinusoid of 3.14159 Hz?  That isn't going to repeat very well.  But who cares?  Imagine drawing this sinusoid and marking your drawing at points precisely spaced 1 msec apart (1000 points/sec).  The points will probably all be different, but they will be the best approximation you can get to this "odd" frequency.  Particularly if the carrier (1 kHz) is enough higher than the frequencies you are trying to deliver, you'll get an excellent approximation.  

 

And there are LabVIEW functions that already do this (though it's not a bad exercise for you to write a little LabVIEW routine to do this yourself -- all you need to know is the formula for determining the value of a sinusoid of a particular frequency as a function of the sampling interval (call it dt) and the index of the point (where by "index" I mean is it the 0th, 10th, 45698th, or what point).

 

Bob Schor

0 Kudos
Message 8 of 27
(4,762 Views)

Hi Bob,

 

Thanks for the reply.

I didn't mention in the original post that I was using DAQ Mx Write, set up for continuous samples, so that I would download the waveform once, and let the DAQ repeat the wave endlessly until I tell it to stop (a remnant of old slow computer days with other tasks taking up the limited processing power).

 

But, if I rewrite it to so that I use a timeout (say every second), and write 1000 samples (for example) every time the timeout triggers, then I need to make an adjustment to the Sine Waveform VI generation.  The frequency of the waveform is as the user entered, and the amplitude is as the user entered.  If I set 'Phase' to False, then the Waveform VI will generate the next 1000 pts in the waveform, starting where it last left off.  I can then feed that to the DAQ Mx Write VI.

 

Did I understand your suggestion correctly?

0 Kudos
Message 9 of 27
(4,728 Views)

Yes, indeed.  In the Bad Old Days, where all we had was a single D/A converter, I wanted to generate a "sum-of-sines" at very low frequencies (for example, 0.02 to 1 Hz, with a period of about 6 minutes (I forget the particulars, this was a few decades ago).  What I really generated was a single waveform at a sampling rate of 65,536 points in 6 minutes (about 200 points/second) -- I had a sine table in memory and 8 "pointers" into the table so I could easily look up the values of the 8 harmonics of the sine frequencies I was using and add them together to send to the DAQ.  Computers are way faster now, hardware is much better, and we have LabVIEW (instead of Macro-11).

 

Bob Schor

0 Kudos
Message 10 of 27
(4,724 Views)