LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

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

Solved!
Go to solution

When I had a similar challenge like this years ago, I talked to my users and realized they only needed to step in frequencies of 100hz.  So I made the UI have the controls jump by 100Hz, allowing them to enter values from 2Khz to 100Hz, but only in 100Hz steps.  Since the two sine waves (or N sine waves) would all have a common frequency I could calculate the number of cycles each would have to go through before getting to the same point in the wave an starting over, with some simple math.  So the 1000Hz wave needed to repeat 10 times, while the 100Hz wave repeated once.  I can't remember how I did the number of samples but it was using NI's functions for generating waves which I think had inputs for something like number of samples or dT.

0 Kudos
Message 11 of 27
(1,671 Views)

It is far more difficult to output two asynchronous sine waves on two channels than one sine wave on one channel.  Your quickest solution involves buying a second USB-6212 and run each with independent buffer sizes and clock rates.

 

If that is not an option than you have one more choice as stated in the datasheet:

USB-6212 AO waveform modes:

Non-periodic waveform, periodic waveform regeneration mode from onboard FIFO, periodic waveform regeneration from host buffer including dynamic update

 

I don't have any sample code for you, but it is possible to create a large buffer in host memory and have it transferred using a special USB Bulk mode when the FIFO memory is half full.  The two sine waves still need to be generated with independent phases and added to the buffer, but the timing demands would be much lower than feeding the FIFO directly.

 

Michael Munroe, CLD, CTD, MCP
Automate 1M+ VI Search, Sort and Edit operations with Property Inspector 5.0, now with a new Interactive Window Manager!
Now supports full project automation using one-click custom macros or CLI.
0 Kudos
Message 12 of 27
(1,657 Views)

You can do this another way. Let's use your example:

  1. 1 Hz Sine Wave and 1.5 Hz Sine Wave
  2. Find the Least Common Multiple of the Two Waves; in the case 3 Hz
  3. Make 3 1Hz sine waves and 2 1.5 Hz sine wave in a 1000 pt buffer.
  4. So now you have a continuous buffer
  5. Find that buffer into your DAQ AO out.
  6. Set the sample output rate to 1000/3 or 333Hz.

In this case you need to adjust your output frequency with respect to the least common multiple, but you now have only one buffer and do not have to continuously regenerate it. Basically, it is pick your poison, regenerate buffer or make one buffer and mess with the output frequency.

 

mcduff

0 Kudos
Message 13 of 27
(1,655 Views)
Solution
Accepted by topic author DMJeff

If you follow Hooovahh's line of thinking (and I'd highly endorse it), you'll be able to write once to the task buffer and then let the task handle regeneration indefinitely without further interaction from your code.  While continuously calculating new sine wave chunks and feeding them to the task is certainly *also* a viable option, I'd opt for the regeneration approach whenever feasible.

 

So let's say for example that your users are presented an *integer* control for selecting BPM.  Well, then you already know without question that any value they pick will fit an integer # of cycles into a 1-minute buffer.  So you just need to generate 1 minute worth of samples for each sine wave.  Each sine wave's BPM is the # of full cycles that will fit in that minute. 

    Note: with similar reasoning, you need to make sure your task sample rate fits an integer # of samples exactly into 1 minute.  This isn't too hard, just don't "get cute" with your sample rate.  I'd recommend 200 Hz or higher to give you at least 100 samples per sine wave.  In fact, I'd recommend you simply pick from among 200, 500, and 1000 Hz for sample rate.  All will let you define *exactly* 1 minute worth of samples.

 

(On a partially related note, if you ever find yourself with the need to regenerate an extremely precise but mathematically "inconvenient" frequency, you can explore this old thread I was in long long ago, but then recently revived and updated at the end.)

 

 

-Kevin P

 

P.S.  I remembered to refresh before posting and some new stuff came in since I started this reply.  Both have good info, I still like Hoovah's idea better.  Users probably *don't need* infinitely variable BPM settings.  Sometimes you can simplify your programming by limiting your user's options to a reasonable subset of infinity.

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 14 of 27
(1,651 Views)

Hi Michael,

 

Thank you for the suggestion.

 

I thought about a second DAQ, but between the cost and the delivery lead time, I thought I'd give a software solution a chance.

 

Thanks

Jeff

0 Kudos
Message 15 of 27
(1,643 Views)

Hi McDuff,

 

Thanks for the suggestion.

If it was just my original example that'd work.

Unfortunately the user needs more control than that.

115 Hz, 25 Hz, etc. so it isn't as straight forward.

 

Thanks,

Jeff

0 Kudos
Message 16 of 27
(1,640 Views)

Hi Kevin,

 

Well, duh, (sound of hand hitting forehead), Thanks.

I just limited the user to picking an integer number of beats per minute (that is close enough resolution for them).

Then I set up the Sine Wave generator for 1000 samples/sec, 60,000 samples.

That's a round minute.

With those changes, the existing code works.

 

Thanks,

Jeff

0 Kudos
Message 17 of 27
(1,634 Views)

Hi Bob,

 

I spent some time rewriting my code to do the above...

At first call, set the sine wave function to 'reset phase', and ask for 1000 samples and 1000 samples/sec.

At subsequent call, do not reset the phase, with the same 1000 samples and 1000 samples/sec.

 

If I set up the sample rate on the output to finite samples, 1000 samples, 1000 samples/sec. I get error -200288 (attempted to write sample 2000 relative to current position).  The output only shows voltage on the first second, then it goes flatline (consistent with the error message).

 

If I change the sample rate to continuous samples, then I get warning 200015 (maybe writing old data), and the output is all kinds of weird redirections and stuff.

 

Just thought I'd share what I learned.

I ended up going back to the original code, changing it to write 60 seconds worth of data (60,000 samples) and limiting the user to integer cycles per minute.

That is working at the moment.

 

Thanks for the thoughtful suggestion,

Jeff

 

0 Kudos
Message 18 of 27
(1,632 Views)
Solution
Accepted by topic author DMJeff

Since you seem interested in trying new things, I'd encourage you to explore Bob's suggestion a little further.  Back in msg #7 I mentioned a shipping example that demonstrates a way to use continuous generation while iteratively writing sine wave chunks to the task.  Check it out.  Compare it to what you tried that didn't fully work out.

 

It's a good technique to have in the toolbox -- regeneration isn't always a feasible option.

 

 

-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).
0 Kudos
Message 19 of 27
(1,618 Views)

Hi Kevin,

 

I took a look at the example, thanks.

It is using the Basic Function Generator to create the sine wave, and that's okay.

The example takes the phase out passes it back using a shift register as the phase in.

I tried that instead of my code and got the same results.

 

I have been using the sine wave generator, the help text explains that it is reentrant, and will 'remember' the phase out and use it as phase in (so you don't have to do the shift register yourself) unless you set the 'reset' flag to true, in which case the sine wave generator restarts.

 

I thought that perhaps the use of the sine generator twice, even though it says it is reentrant was causing problems.  So I tried using the square wave generator instead, and while the actual wave that was output was 'different' I had the same problems.

 

So, I used the basic waveform generator, and told it to generate a sine wave.  Save problems.

 

I then created a new VI, doing just the analog output tasks, so I didn't have to worry about all the  rest.  Same issues.  I attached the files to this so you can take a look if you'd like.

 

I have it working the 'old way' sending 60,000 samples down and letting the DAQ take it and run, but I would like to know why this way doesn't work.

 

Thanks for thinking about this,

Jeff

 

0 Kudos
Message 20 of 27
(1,608 Views)