- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Ive been trying to use pwm to control a heater using feedback from a thermistor. Ive asked a similar topic before about implementing a PID controller but was wondering if anyone knows of a simpler way to decently regulate the output. currently all the code i have does is kind of use reduced PWM duty as the set point and measured gets nearer to each other. this either causes an overshoot or doesn't quite reach the set point.
any advice guys?
thanks
Solved! Go to Solution.
- Labels:
-
PSoC 3
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Depending on the time the system uses to react your closed loop will either overshoot or converge asymptotic. Only by fine-tuning the PID parameters and by stabilizing (thermal Isolation) of the heater and / or forcibly stirring the heated liquid will help.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Depending on the time the system uses to react your closed loop will either overshoot or converge asymptotic. Only by fine-tuning the PID parameters and by stabilizing (thermal Isolation) of the heater and / or forcibly stirring the heated liquid will help.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I can only recommend to follow the "improving the beginners PID" tutorial series. Its quite comprehensive - I learned PID from there, and its not exactly complicated (read the value you want to control, make some calculations, write the value to the peripheral that controls your setup).
The tricky part is in finding out the correct P,I, and D values. For tuning look at the Ziegler-Nichols-method (tl;dr: set I and D to 0, start increasing P until your control loop oscillates. With this frequency you then calculate P, I, and D).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
thanks for your quick replies folks. say i only use the the P term for initial testing and understanding then Output = kp * error
Another thing is how do i relate the output to a PWM duty cycle? using an 8 bit PWM with a range of 0-255
thank you guys
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The function PWM_WriteCompare() will set the duty-cycle . Use a value between 1 and the programmed period value.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi bob, The PWM_WriteCompare() function is being used to drive a h bridge, At the moment the value of between 0 and 255 was randomly chosen, How does the Proportional output alter the PWM duty cycle? would i not need to relate the output function with the proportional function to the PWM's duty cycle somehow as it should take into account he overshoot in temperature and compensate for it?
ive got a setpoint which is a temperature reading in degrees C and the feedback is from a temp sensor also in degree C.
Sorry if my question seems a bit redundant
thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Duty Cycle is Period / Compare *100, Quite easy.
The PID controller parameters (KP, KI, KD) are taking care of overshoots. Proceed as hli suggested, this is the only way.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Bob, thanks for the reply. Ive read the link hli sent to me, Its just i still have an issue with what you're saying. it makes a lot of sense. I know that 255 will equal 100% duty cycle and 128 will be 50%. Its the PID output function that i have an issue with. I know it can get the error term by reading the difference between set_temp and actual temp. but wont the PID function I called output need to be multiplied or somehow control the duty cycle in the PWM_writeCompare() function?
I have the PID output which is currently just the error*Kp, but doesnt the output function need to be in the WPM_writecompare() function? the value i set in the write compare function directly controls the duty cycle and therefore the heater.
ive been doing something like this PWM_WriteCompare(192), roughly 75% Duty cycle. I have two PWM_WriteCompare functions because the two PWM outputs are connected to IN1 and IN2 of the Hbridge im using. I can reverse the direction by giving a duty cycle value to one write compare function and have the other PWM write compare function tied to ground.
The two PWM_writeCompre functions are my only outputs.
If have simple if statement that i know causes an overshoot.
its simply
if(set_point>actual_temp) //cooling direction
{
PWM_writeCompare1(192); //etc
PWM_writeComopare(0); //it tied to ground
}
then to heat the heater/peltier i do the opposite with the write compare.
How does the PID output function interact with the PWM_writeCompare function?
Sorry for posting a silly question, thanks for all your help so far i greatly appreciate it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The PWM has two outputs which can be programmed with a dead-band suitable for h-bridge. Because the characteristics of the peltier are different for heating and cooling you may need two different PIDs connected to two PWMs. You may select which one is active using a MUX.
wont the PID function I called output need to be multiplied or somehow control the duty cycle in the PWM_writeCompare() function? This the KP performs. You might use a limiting function for duty cycle >= 0 and <= 100%
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ok,
So would it be something like this? For the moment i only have the Proportional and i will put limits on the PWM as well as implement the Intergral and derivative functionalites.
Output = kp * error;
PWM_WriteCompare1(00000);
PWM_WriteCompare2(Output);
thanks very much for your help
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ok thanks. my PWM config is 8 bit resolution, two PWM outputs, with deadbands for 2-4 clock cycles. a 100kHz clock giving a period of 2.56mSec. its also a less than type count.
My duty cycle is between 0 and 255, Its just how will the output function error*Kp increment my duty cycle?
ive set KP initially to 1, and the error will presumably be set-point-actual_temp.
given a set point of 30c and a measured temp of 21C. the error will be 9, and the output will be equal to 9? wont that mean that the pwm duty cycle will be 9/255? PWM_WriteCompare1(Output or 9/255)
Will this value only increase with the use of the full formula i.e the integral and derivative?
Sorry its the output function controlling the duty cycle im having issues with.
thanks for your assistance
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
A pure P-controller always has got a (small) error.
An I-component will make sure that there is no long-term error adding up.
The D-component will allow for a short reaction time (Not usable for slow reaction-times as heating or cooling.
Your example from above is right, duty cycle will be 900/255 = ~4%. When the temperature climbs too slow, you can increase KP.
Assume KP = 50, So in your above example you get 9*50 = 450. Limited to 0..255 you get 255, system is heating up. When the difference is only 1°C you get 1*50 that is 5000/255 = ~20% duty cycle.. When that is about what radiation cools your system, you have a stable situation.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Bob,
thanks for the reply. I see now how it controls the duty cycle. simple yet clever as you and hli have been putting it ot me.
Ive read that the derivative might not be applicable to a heating cooling situation especially given the slow time constant of heating/cooling.
I was looking at the integral component.
This is defined as: ki * errSum
where the error sum is equal to error * timechange.
unsigned long now = millis();
double timeChange = (double)(now - lastTime);
it gives a variable 'now' and its equal to millis(), im just trying to figure out how this is calculated or is it a random milliseconds number.
i.e millis(100); is it the same a cydelay in a manner of speaking,
thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The I-part of the PID ensures that the error may become zero within a longer time. A side effect will be that the summed error will be corrected later producing some unwanted variance at that time. The I-part is good when you mix two chemical parts with two controlled pumps. At the end all errors are extinguished and in the resulting reservoir the concentration is exactly as wanted. What are you designing? A DNA multiplier?
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
hi, thanks for replying Bob, actually I am only setting a temperature on a heater module. I had an algorithm which caused some overshoot and which i s why i started looking into a software based PID type controllers. I wanted to ask on the forums here as I was certain someone would have a little more experience than I myself. I was thinking of having simply a Proportional controller or a PI controller. As ive been reading and you've also pointed out the derivative part may not be needed. I haven't downloaded the code yet but the Proportional may yield decent results. I wasn't sure about the Integral component, whether or not it would be needed which is why i was asking about it and how the 'now' was calculated.
With regards to the heating and cooling characteristics being different and possibly needing two separate proportional components wouldn't that effectively mean that the proportional gain will be different? i.e a Kp for heating and maybe a Kp1 for cooling. I have noticed that cooling tends to require a greater effort which translates to a higher duty cycle.
Thanks for your assistance
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
A peltier "pumps" energy and -as a side effect- consumes energy into heat. Thus been said, heating is more efficient than cooling. So you will need different KPs as you already deducted.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes, the peltier is not exactly efficient. I am not sure if I need to implement the integral component as I am only regulating to maybe half a degree Celsius accuracy. The proportional component may itself yield decent regualtion. The PID controller that hli provided a link for seems to cover every aspect of the PID controller making it similar to a profession/industrial grade controller. Although the author of that link stated that the PID function is called randomly wif a specific sampling interval is not applied. However for my purposes it may not be necessary.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
When calling the P(ID) controller with a fixed timing, the algorithm becomes smaller using less multiplications. This is essential for high-speed controllers or heavy duty systems which is not the case with your project.
I would suggest you to
- Focus on a PI controller with a rather small KI
- Reduce the reaction-time of your heating/cooling by forced movement of the media (stirring)
- Nearby placing of sensor to heating within the media
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for your reply Bob, Im getting quite good accuracy with the P controller alone. I was interested in adding the Integral component.
I am unsure as to how 'now' is derived, as seen here.
unsigned long now = millis();
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am unsure as to how 'now' is derived, as seen here. Seems to be from an internal ms clock / timer.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Bob, the millis() function counts the amount of milliseconds since the program was run. What would be a good method to do that in the Psoc? A free running counter or is there a cypress equivalent?
thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You may use a 1ms timer and increment a 64-bit variable in the interrupt handler. This will give you a nice clock. Care to declare the variable as "volatile" and encapsulate read accesses between enter and exit critical section. See CyEnterCriticalSection() in the "System Reference Guide" (from Help menu)
Bob