02-22-2013 02:38 PM
Hello all,
I am currently writing a VI to a USB-6215 that will use a PID controller to alter the PWM duty cycle for a 12V case fan using the difference in percentage of two humidity sensors. Addtionally, there is a similar process that will measure the difference between two thermocouples and use a PID controller to alter the PWM duty cycle to a 12V Peltier heating device.
My trouble currently is writing the PID output as a PWM signal for controlling the equipment in each independent process.
I have attached what I have done so far. Is there any help that you guys might be able to provide?
Many thanks.
02-22-2013 03:49 PM
Your USB-6215 has a built-in timer/counter that can generate a PWM signal in hardware. I recommend that you use that, as described here: http://www.ni.com/white-paper/2991/en. Then you just need to set the PWM output limits appropriately (minimum duty cycle just greater than 0, maximum duty cycle 1 or whatever is appropriate for your application) and tune the PID loop. I'd also suggest that you avoid the DAQ Assistant and use the DAQmx functions directly for more control (and to eliminate use of the dynamic data type, which seems to cause more problems than it solves).
The first step should be a simple VI that lets you enter a duty cycle and sets that value. Make sure you can control the fan. Then integrate the PID.
02-25-2013 01:56 PM
Thank you for your help so far. So I implemented an altered form of the PWM function that you posted, but unfortunately I am unable to convert a certain numeric value (a set ending point, say 0.05 of output duty cycle) to a boolean value that when connected to the Stop function of the while loop, would end the test. Basically, I'm having trouble creating an end condition for the entire loop based on the output of the PWM function. Is there any help that you might provide that will achieve this ending condition? Attached is my current VI.
Thanks!
02-25-2013 02:04 PM
I don't understand what you're asking. Are you trying to end the test when the PID output reaches a particular value? How do you know the PID output will ever reach that value?
Perhaps the "Less Than" or "Greater Than" functions would do what you want? I don't recommend checking equality of floating point values since very small differences will cause two values to be unequal, but you can check for rough equality by subtracting, taking the absolute value, and checking if the difference is smaller than some amount.
You didn't include the PWM subVI which makes it harder to understand your code.
02-25-2013 04:03 PM
Sorry for the confusion.
What I eventually want to achieve is to have the output of the PID controller (labelled in the attached file under teh block diagram as 'Fan PID Controller') to alter the duty cycle of the fan (using the DAQ.mx Function Labeled 'PWM Train') so that eventually as the PID output becomes smaller, the duty cycle of the fan will drop below a desired PWM output level, which would trigger the stop function of the overall While loop.
What I was having difficult with is managing to connect the 'PWM Train' output to the stop function of the while loop. I am unable to find a way to convert the output of the PWM Train DAQ.mx function to a Boolean output that can be read by the Stop function.
Does this help explain what I want to do better? Or is more information required? Thank you very much for all of your help.
02-25-2013 04:06 PM
Again, you didn't attach the PWM VI, so I can't see what it's doing. However, my comments in the previous post are still valid. You don't need to "convert" the number to a boolean. If you want to compare the PWM duty cycle to a fixed value, use the "Greater Than" or "Less Than" comparisons, as I suggested. The output of those blocks is a boolean.
02-25-2013 04:28 PM
Curses! I feel like a grade A fool right now. Here is the PWM Sub-VI, all I basically did was attach an indicator to the Shift Register for the PWM signal so that I would be able to attach that output to the 'Fan Duty Cycle' indicator and the Stop function. Is this adequate?
Thanks!
02-25-2013 05:02 PM
@shelgeson wrote:
Here is the PWM Sub-VI, all I basically did was attach an indicator to the Shift Register for the PWM signal so that I would be able to attach that output to the 'Fan Duty Cycle' indicator and the Stop function. Is this adequate?
No, it's not. That subVI will run forever (well, until you click its Stop button) which isn't what you want. You want it to run once per iteration of the larger while loop. You also want to create and destroy the timer task only once, not every time you call the subVI. I'd remove the subVI, move the logic into your main loop, and put the task creation and destruction outside the main loop. Also, use a shift register to track the previous duty cycle, instead of a local variable.
03-06-2013 04:08 PM
Hello again. I placed the PWM loop logic for both loops in the VI as you suggested, and it seems to work. However there are a couple more problems that we have run into.
1. The DAQ assistant that we use to aquire our analog channel samples (2 Humidity, 2 Temperature) only will aquire one sample, at the very beginning of the test. We want them to collect a sample for every iteration of the main while loop, and use that in conjuction with our PID controllers that will alter the PWM loop duty cycles. How should I wire this up so that it collects a sample every iteration? I've tried altering the timing settings in the DAQ assistant properties menu, but this hasn't done much. The sample probes are functioning properly, so it isn't a problem with our instruments.
2. For the humidty values, there is a branch where we find the difference between the two, and plot that in a waveform graph. Like in problem 1, because we are only getting one sample, it will not plot w/respect to time. Even the one sample that we do obtain does not plot. I was wondering if this was related to the where the Waveform Graph generator is located with respect to the whole While loop. Currently I have it outside the loop (assuming that it would create/destroy itself every iteration), but this too has not worked out. Where should I locate it so that it generates the graph that I seek?
3. FInally, I am using values of the duty cycle from the 'Fan PWM Loop' to form a running average that when compared to a set value using a 'less than function' will trigger the stop function for the entire loop. I have connected the duty cycle output from the PWM loop to a shift register for the entire loop, and using stacked shift registers to calculate that running average. However, this runs only once, despite the PWM loop running continually.Do I have the logic for this running average set up correctly, or will more need to be done so that my overall while loop stop function can actually be triggered?
I have labeled the problem areas on the VI. Thanks again for all of your insight.
03-06-2013 06:22 PM
I don't think you understand how loops work in LabVIEW. I highly recommend that you run your VI with Execution Highlighting turned on (the lightbulb icon in the toolbar). It will be really slow to watch, but it will also be enlightening. After you see what your code does, I suspect you'll be able to fix it.