I am trying to control the duty cycle of a counter output with a PID control.
I found a VI online that will allow you change the frequency or duty cycle while the program is running by using property nodes inside the while loop and from the frequency control or the duty cycle from the duty cycle control , what I would like to do is use the output from the PID to set the Duty cycle.
The entire purpose of this is to create a temperature-controlled oven of sort.
This issue is I just am not sure of a way to write from the inside of the loop structure to the counter control.
I have included a copy of my work so far .
Solved! Go to Solution.
I'm on LV2016 and can't look at the code unless you backsave to an earlier LV version.
I'll alert you to something that I *think* is still true: changing duty cycle alone will not have any effect. You have to *also* re-write the frequency value. If you set your changes by calling DAQmx Write, both inputs are required so you kinda have to write both. But if you were to try to change duty cycle alone by writing to a DAQmx Channel property node, nothing would happen until there was a subsequent write to the Freq property.
<time passes...> Yup, just checked, still true on an X-series PCIe-6341.
I hope you had a good weekend.
attached you will find my code in LV2016
I have tried several things just cant get past this last hurdle
I'll try to make some minimal mods to the code you posted. Here's some more explanation to go with it.
1. I have no idea whether you've come up with appropriate PID gains for your system. But I *AM* sure that you should not be coercing the output between 0.5 and 100. The counter duty cycle needs to be a *fraction* that ranges from 0.0 to 1.0 (though true 0 and 1 are not actually possible, there must be some amount of both on and off time).
2. Embedding an event structure in a loop that's being slowed down and paced by the AI task is a bad idea.
3. Most (possibly all?) counter devices have a constraint that doesn't get a lot of publicity. Namely, once you write a new set of pulse params (freq & duty cycle), you're not allowed to write new ones to the task until the previous ones have actually been used for a cycle.
If the pulse train is much faster than the loop rate, this problem doesn't tend to show up. But your default values suggest a pulse rate of 1 Hz and a loop rate of about 10 Hz. That's a problem.
4. The call to DAQmx Read should be the *only* thing pacing your loop. You don't need (and shouldn't add) the other 100 msec wait. The additional use of a 100 msec timeout on the already-undesired event structure also doesn't help.
New behavior of modified code:
- loop is timed only by DAQmx Read for AI
- immediately after each AI sample is read, we determine if the counter task is "ready for new pulse param values". If so, we're going to write the latest Freq and (calculated) duty cycle.
- I now coerce your duty cycle between 0.005 and 1. I was assuming your previous range of 0.5 to 100 were meant as %ages, thus 100x too large
- I addded an indicator for the uncoerced output of the PID calc. I suspect you need to work on your gains and this indicator will give you some clues.
thank you for the input.
I had no idea about the ready for new value property node that makes it much easier to control.
I had tried to slow down the execution of the loop to allow for completion of the cycle that was a bad idea.
wow this is doing what i had set out to do.
and I have learned more.
Again thank you for the input big help and great learning example.
have a fantastic remainder to your week