12-21-2006 03:26 AM
12-21-2006 02:49 PM - edited 12-21-2006 02:49 PM
Message Edited by Kevin Price on 12-21-2006 03:49 PM
01-09-2007 02:20 AM
01-09-2007 11:05 AM
Glad it helped! Just thought I'd add one more little tidbit as an FYI.
In the code snapshot you posted, the frequency is updated by writing to a DAQmx Write Property node. Once upon a time in a thread, one of the guys from NI said or implied that it should be slightly more efficient / fast to change frequency using the regular DAQmx Write.vi rather than with a property node.
The other possible issue with writing to a property node is that the two pulse parameters are not treated equivalently (unless this has changed in a more recent version of DAQmx). One is "active" and the other is "passive." Fortunately for you, the freq property is "active," and will cause the hardware freq to update while re-using the old value for duty cycle. However, the duty cycle property is "passive." Writing the duty cycle value alone will just store it there, and the hardware pulse train won't update until a freq value is written. So people generating PWM control must always write the same constant freq value in order to "activate" the new duty cycle value. I *think* this same principle applies to pulse trains defined in terms of high and low times/ticks, though I'm not sure which of the two parameters is the active one and which is the passive one.
Most if not all of this stuff becomes a non-issue if you update freq using DAQmx Write.vi. I'm not at a LabVIEW PC to test right now, so I'm not sure if you can call DAQmx Write.vi without wiring both freq and duty cycle (or both high and low times/ticks). If you *can*, I'm not sure what it uses as a default for the unwired input. I would *hope* an unwired input would mean "retain prior value."
-Kevin P.
01-10-2007 02:21 AM
In the code snapshot you posted, the frequency is updated by writing to a DAQmx Write Property node. Once upon a time in a thread, one of the guys from NI said or implied that it should be slightly more efficient / fast to change frequency using the regular DAQmx Write.vi rather than with a property node.
I suppose I have always wondered if there is an actual difference between different ways of programming, like with property nodes and write vi's. Appearently there is 🙂
The other possible issue with writing to a property node is that the two pulse parameters are not treated equivalently (unless this has changed in a more recent version of DAQmx). One is "active" and the other is "passive." Fortunately for you, the freq property is "active," and will cause the hardware freq to update while re-using the old value for duty cycle. However, the duty cycle property is "passive." Writing the duty cycle value alone will just store it there, and the hardware pulse train won't update until a freq value is written. So people generating PWM control must always write the same constant freq value in order to "activate" the new duty cycle value. I *think* this same principle applies to pulse trains defined in terms of high and low times/ticks, though I'm not sure which of the two parameters is the active one and which is the passive one.
The stepper motor driver we use doesn't really care about duty cycle, so it's just at it's default of 0.5. Before we used the frequency property node, we used a double node to write both the high and low time. It seemed to work in the same way the frequency property node does.
Most if not all of this stuff becomes a non-issue if you update freq using DAQmx Write.vi. I'm not at a LabVIEW PC to test right now, so I'm not sure if you can call DAQmx Write.vi without wiring both freq and duty cycle (or both high and low times/ticks). If you *can*, I'm not sure what it uses as a default for the unwired input. I would *hope* an unwired input would mean "retain prior value."
Duty cycle is a required input of write in counter 'single channel single sample' mode. I have replaced the frequency property node with a write vi. I don't notice any difference, but since it should be slightly more efficient I will keep it this way. See the attached, but not inline showing, screenshot.
01-11-2007 09:54 AM - edited 01-11-2007 09:54 AM
Message Edited by Floris. on 01-11-2007 04:58 PM
01-12-2007 08:42 AM
Hmmm, that's a new one on me. How exactly have you determined that the property node gets stuck? And when you say "stuck", you mean that the value remains stuck at False while the loop keeps on running, right?
The following is just speculation, but what the heck -- let's play detective, eh?
The problem happens pretty rarely, but chronically. That leads me to suspect something a bit random, something with a low probability of happening at any instant, but nearly inevitable when you run your loop hundreds of times per second.
That in turn makes me think, "race condition." I get suspicious of the way you're "idling the counter" using a hardware pause trigger. That hardware pause trigger is either controlled by a different part of the code or by an external signal. Either way, the timing of the Pause / Unpause transitions are not sync'ed to this loop.
Let's suppose on iteration i that all the right conditions are met and you do make the call to DAQmx Write to update the pulse freq. However, before the pulse-in-progress is completed, let's suppose that the pause trigger transitions to the pause state. Now on iteration i+1 the property node will be False because the counter hasn't generated a cycle with the new frequency yet. And it will keep on staying False as long as the pulse train is paused.
And, uh, well, now I'm stuck again because I don't see why it wouldn't get back to normal operation when you Unpause the pulse train. Are you sure that the code running the pause trigger signal isn't somehow stuck?
Finally an idea for a workaround. Unless your pause trigger needs to be hardware-timed, you could choose not to use one at all. You can call DAQmx Stop to stop the pulse train and then DAQmx Start to re-start it. Stops and Starts aren't too terribly slow -- it's the Clear and Re-Creates that you'd want to avoid inside a loop.
-Kevin P.
01-22-2007 07:51 AM
Hmmm, that's a new one on me. How exactly have you determined that the property node gets stuck? And when you say "stuck", you mean that the value remains stuck at False while the loop keeps on running, right?
See the error handling generating code in never_ready.png 🙂
That in turn makes me think, "race condition." I get suspicious of the way you're "idling the counter" using a hardware pause trigger. That hardware pause trigger is either controlled by a different part of the code or by an external signal. Either way, the timing of the Pause / Unpause transitions are not sync'ed to this loop.
We pause the counter via software output --> DIO7 --> advanced piece 'o hardware (a wire) --> PFI1. Of course, we've looked for a software solution at first.
Let's suppose on iteration i that all the right conditions are met and you do make the call to DAQmx Write to update the pulse freq. However, before the pulse-in-progress is completed, let's suppose that the pause trigger transitions to the pause state. Now on iteration i+1 the property node will be False because the counter hasn't generated a cycle with the new frequency yet. And it will keep on staying False as long as the pulse train is paused.
And, uh, well, now I'm stuck again because I don't see why it wouldn't get back to normal operation when you Unpause the pulse train. Are you sure that the code running the pause trigger signal isn't somehow stuck?
Yes, we are sure. The stepper motor can still move, but only at a fixed speed.
Finally an idea for a workaround. Unless your pause trigger needs to be hardware-timed, you could choose not to use one at all. You can call DAQmx Stop to stop the pulse train and then DAQmx Start to re-start it. Stops and Starts aren't too terribly slow -- it's the Clear and Re-Creates that you'd want to avoid inside a loop.
Before we used a property node to update the counter frequency, we had a test program that used stop and start blocks to pause the motor and restart with another frequency. This actually was too slow. Nevertheless we've tried to rewrite the code, but I got discouraged because the 'CO.RdyForNewVal' property node doesn't like it when the task is stopped and throws an error.
The program as it is now works well enough. It seems bug free, we only sometimes encounter labview 'features'. Thanks for all the help.
Floris