01-08-2020 09:19 AM
Hi,
I am struggling with the exact same problem, and can't find a solution... Have you found it since you posted the problem?
Best regards,
M Guibert
01-08-2020 10:28 AM
Will need more details about your "exact same problem."
Assuming you need to smoothly transition the output signal down to 0 volts, you'll need to know what value to start from. You may be able to control that, but if not, you'll need a way to inspect it. And then the next steps will depend on whether the task remains running or whether it has already been stopped.
-Kevin P
01-08-2020 11:06 AM
Hi,
I want to run waveform generation for a very long time, having the possibility to change waveform during the execution of the programm (ie amplitude...). But when I press stop, I'd like the generation to stop on a finite period of the generated signal.
In the attached exemple, I don't understand why it does not stop on a finite number of period when existing the while loop. I noticed that during the first execution of the loop, 350 points only are generated (instead of 1000), while next iteration of the loop produce around 1000 points as expected...
I finally found something that worked, I check the number of points really generated and compare it to the number of points expected after exiting the generation loop and before stopping the task... It seems to work taht way...
I ve attached the code bellow...
regard,
Matthieu
01-08-2020 02:30 PM
That's a pretty decent idea, but it isn't gonna be foolproof under a range of different conditions.
1. I'm not sure that the property "TotalSamplesGenerated" is going to be up-to-the-microsec accurate. It probably *is* your best available estimate though.
2. Some small software execution time will take place between your query of those properties and the instant when the board *actually* stops generating in response to your DAQmx Stop call. This may be small, but it can't truly be 0.
3. These factors may not usually have a tangible effect at present with a modest sample rate of 1000 Hz, but there is some higher sample rate where they usually *will*. Dunno if you need to be concerned with that for this app.
4. You're more prone to these problems on a cDAQ device than you would be on a desktop device due to the USB or Ethernet connection.
5. At present, you have very "nice", convenient values for waveform freq, sample rate, and # samples. Your requested sample rate of 1000 Hz will likely be *exactly* possible on many DAQ devices and your other parameters have you creating *exactly* 1 full cycle of your waveform on each loop. The graph doesn't change at all from iteration to iteration.
Thus, when you poll properties to try to land at the "Current Write Position", you *happen* to be conveniently at the end of one cycle of your waveform. But if you were to try a different combo of those AO parameters, your "Current Write Position" might be at *any* phase of your waveform (and thus at any value, not always ~0).
6. In general, I don't think you're going to be able to rely on getting the AO task to stop generating at the exact right instant when it just generated your desired target value (I'm kinda assuming 0?).
7. But there are other options. I'll describe a couple, assuming you have a target final output voltage of 0. Both start immediately after exiting the AO Write loop.
8. This kind of method can be made "smoother" but requires more time to pass before you know your AO signal is right.
Since you know the last voltage value you sent to DAQmx Write, create some kind of smooth ramp (or whatever) from that value to 0. Send this data to DAQmx Write. Then go into a loop where you keep sending 0 volt waveforms to DAQmx Write until it's time to stop.
When is it time to stop? Either when your AI can *confirm* that you've gotten yourself to 0 or when you can calculate and know that you've written 0's long enough that some of them would have to have gotten all the way through both the task buffer and device FIFO to be generated as 0 V signals.
9. This method will spend a brief time at some unknown plateu voltage before smoothly transitioning to 0.
Stop the AO task. Check your AI loopback to confirm the constant voltage you happen to have stopped at. Create your ramp (or whatever) from that voltage to 0. Reconfigure AO for Finite Sampling. Write your data, start the task, and wait for it to finish.
-Kevin P
01-09-2020 05:45 AM
HI Kevin,
Thanks for your comments. I had some remarks...
1. I'm not sure that the property "TotalSamplesGenerated" is going to be up-to-the-microsec accurate. It probably *is* your best available estimate though.
2. Some small software execution time will take place between your query of those properties and the instant when the board *actually* stops generating in response to your DAQmx Stop call. This may be small, but it can't truly be 0.
3. These factors may not usually have a tangible effect at present with a modest sample rate of 1000 Hz, but there is some higher sample rate where they usually *will*. Dunno if you need to be concerned with that for this app.
Not important here. Actually, since my generation does not allow regenration, I just need to wait the good amount of time before stopping the task. I might get an error of an empty buffer before I stop, but I can clear that error if it happens
4. You're more prone to these problems on a cDAQ device than you would be on a desktop device due to the USB or Ethernet connection.
YES. I actually imported this code fro an other project that uses a PCI 6221 board, and the behavior was different/ I never had to worry about it, and each iteration of the loop generated 1000 points. It always stopped at the expected time... the problem appeared using a USB Compact RIO device.
5. At present, you have very "nice", convenient values for waveform freq, sample rate, and # samples. Your requested sample rate of 1000 Hz will likely be *exactly* possible on many DAQ devices and your other parameters have you creating *exactly* 1 full cycle of your waveform on each loop. The graph doesn't change at all from iteration to iteration.
Yes, this is why I 've put the frequency control out of the loop so far. I think I will have to count the number of sample generated for each period of my signal, to know when I'll have to stop. Then, I'll have to generate my last waveforme with the exact number of sample needed to finish my period... I might look on how it is done in the sound and vibration toolbox (if the code is open), since they might use this kinf of solutions for frequency sweep...
8. This kind of method can be made "smoother" but requires more time to pass before you know your AO signal is right.
Since you know the last voltage value you sent to DAQmx Write, create some kind of smooth ramp (or whatever) from that value to 0. Send this data to DAQmx Write. Then go into a loop where you keep sending 0 volt waveforms to DAQmx Write until it's time to stop.
When is it time to stop? Either when your AI can *confirm* that you've gotten yourself to 0 or when you can calculate and know that you've written 0's long enough that some of them would have to have gotten all the way through both the task buffer and device FIFO to be generated as 0 V signals.
I thought about that, but my solution works so far and insure my sinus signal is good until the end of the generation, which is mandatory for my application.
9. This method will spend a brief time at some unknown plateu voltage before smoothly transitioning to 0.
Stop the AO task. Check your AI loopback to confirm the constant voltage you happen to have stopped at. Create your ramp (or whatever) from that voltage to 0. Reconfigure AO for Finite Sampling. Write your data, start the task, and wait for it to finish.
Again, not allowed for my application.
Thanks again.
Matthieu
01-09-2020 09:56 AM - edited 01-09-2020 09:59 AM
You wrote:
Not important here. Actually, since my generation does not allow regenration, I just need to wait the good amount of time before stopping the task. I might get an error of an empty buffer before I stop, but I can clear that error if it happens
Excellent point! I overlooked the fact that you explicitly don't allow regeneration. That's gonna help. A LOT!
Now you can bring the waveform frequency param inside the loop along with amplitude (and waveform type, if you want). Even "# samples" *could* come inside, but there's probably no particular value in that.
Now we only need to make a slight mod to item #8 I wrote before. Instead of a "ramp" from the last written voltage value down to 0, you'll instead use your knowledge of the param values from your call to the Function Generator vi.
After exiting the loop, your knowledge of Amp, Freq, and ending Phase can let you calculate appropriate params for a 1-time call to the Func Gen that will finish out the cycle you might be in the middle of.
The easy way is to use all those values as-is and only calculate a "# samples" that will more-or-less finish out your waveform period. Depending on factors I mentioned before (the "nice" talk), you probably won't end *exactly* at 0 V. But you should be close enough that you can just append a 0 to the calculated waveform before sending it to DAQmx Write.
Then (because you disallowed regeneration!) you can just loop over the AO task, querying status until you get the buffer underflow error. Then you'll know that your AO generation has completed, finishing a cycle of your waveform, and then explicitly transitioning directly to 0 V for the final sample.
-Kevin P
01-09-2020 10:47 AM - edited 01-09-2020 10:50 AM
Thank you! Calculation of the remaining of the period to generate after the loop is much easier than what I though about in the first time! I didn't think of the fact that I know the enbding phase!
I think this thread can be scored as solved... But I don't know how to do it 😉
01-09-2020 11:32 AM - edited 01-09-2020 11:33 AM
Only the Original Poster to a thread can tag a given response as a "solution". Since our discussion jumped in on the tail end of someone else's original thread, you won't be able to.
Kudos might help though, and would be appreciated... 😁
-Kevin P