PDA

View Full Version : Need help with understanding PID control



Megahertz
- 28th November 2013, 23:16
I have to make a PID temperature control. I do not want to use any existing inc files though they have helped a lot in understanding. I am starting from basics and would like some help in understanding a few concepts. I am starting with only proportional control for now and will develop the whole code as I go along and will post the whole working code at the end. So, here I go:

I have a 12 bit adc with LM35 connected to it. I have a 16f877a which runs the show.
My questions are:
1) When the error is -ve or zero (i.e. current value is greater than or equal to the set point )then should proportional drive become zero? (i.e. if error.15=1 then prop_drive=0)
2) Can Kp be a positive integer between 1 to 100 or is it better to have it as 1-10 with 2 decimal digit. i.e 1.12/2.34/5.88 ....etc?
3) How does a 0-255 duty cycle relates to value in few hundreds or thousands of proportional drive? For example, if MAX set point is 55 degrees or 416 ADC value and current reading is 200, error is 216, lets say kp is 5 then proportional drive will be 216 x 5 which is far higher than MAX duty cycle of 255. So how do I relate the drive to a number between 0-255?

These are the initial questions I am looking for answers for and will have more as I go along. Thanks

HenrikOlsson
- 29th November 2013, 06:09
Hi,

1) When the error is -ve or zero (i.e. current value is greater than or equal to the set point )then should proportional drive become zero? (i.e. if error.15=1 then prop_drive=0)
When the error is zero the proportional term will be zero. When the error is negative the proportional output should be negative (even if you clamp the final output to positive values).


2) Can Kp be a positive integer between 1 to 100 or is it better to have it as 1-10 with 2 decimal digit. i.e 1.12/2.34/5.88 ....etc?
Just a matter of taste. Since PBP doesn't support floating point numbers natively you're going to end up with integers anyway. The more resolution you have the better control you'll be able to get.


3) How does a 0-255 duty cycle relates to value in few hundreds or thousands of proportional drive? For example, if MAX set point is 55 degrees or 416 ADC value and current reading is 200, error is 216, lets say kp is 5 then proportional drive will be 216 x 5 which is far higher than MAX duty cycle of 255. So how do I relate the drive to a number between 0-255?
That's up to you really. If the gain actually IS 5 then the output will gat saturated. But if the gain is represented as you outline above, where 5 might mean 0.5 or 0.05 then the P-term would be 108 or 10.

If large changes in setpoint is to be expected while the regulator is working then I'd suggest you implement some sort of ramp with a slope that the system is capable of following otherwise you'll get into situations as above where there's a HUGE error resulting in a saturated output and integrator windup (which you need to cater for). So, if you (the user) change the setpoint from 100 to 200 then allow the system to internally ramp the setpoint for the regulator up from 100 to 200 along a slope that whatever it is you're regulating can actually follow.

/Henrik.

Megahertz
- 29th November 2013, 21:04
Thanks Henrik. I have got one more question for you, for now:


pid_Kp = $0700 'Set Kp to 7.0
pid_Ki = $0080 'Set Ki to 0.5
pid_Kd = $0225 'Set Kd to 2.14
In your code above, you take $0225 to 2.14, $0080 to 0.5, how is that? I do not see calculations for converting numbers to decimal digits, as you are multiplying them as it is to the error variable. Please explain me how this is working and I will also be interested in knowing what is the maximum number I can assign to the gain this way, I will clamp it later as I intend to use pot for setting these. Cheers

HenrikOlsson
- 30th November 2013, 09:05
It's because the calculations are using the */ operator: 100 */ $0225 = 214
Since the gain variables (kp, ki, kd) are Words the max gain would obviosuly be $FFFF which is equal to an actual gain of ~255. Care needs to be taken not to overflow the output when large gains are used in system where the error cn be large.

/Henrik.

Megahertz
- 1st December 2013, 00:14
Thanks Henrik. So, is there any way I can tell what is the actual gain setting ( like 2.14 or 3.5 etc) before I multiply with 10 or 100. For example just by looking at lets say for example $0324?

I tried the following code, but my duty stays at 255 and is not coming down after overshoot.

'PROPORTIONAL VARIABLES
Error_P Var Word
Kp Var Word
'---------------------------
Kp=$0900

Main:
Gosub Get_Sensor_Value ' Get value from sensor

' ----- PROPORTIONAL CONTROL----------
Error_P=Set_Point-Sensor
Drive_p=(ABS Error_P) */ Kp
If Error_P.15 then Drive_P=-Drive_P

'--------------------------------------
Drive_T=Drive_T+Drive_P '(I used DriveT=Drive_T+... to keep some level of drive)
Duty=Drive_T
Gosub Duty_Mosfet
Pause 250
Goto Main

Duty_Mosfet:
If Duty>255 then Duty=255
If Duty.15=1 then Duty=0
HPWM 1,Duty,500
Return

richard
- 1st December 2013, 06:10
hex 324 = dec 804 , 804/256 = 3.14

HenrikOlsson
- 1st December 2013, 08:52
Hi,
Richard covered the gain calculations, not much to add to that.
Your problem is most likely the line

Drive_T=Drive_T+Drive_P '(I used DriveT=Drive_T+... to keep some level of drive)
Drive_T will accumulate to very large numbers and you don't show what type variable it is. If it's BYTE then you'll be in even more trouble because it won't work properly adding Drive_P when that value is negative. For that to work both variables need to be the same size - which they might be, I don't know since you don't show the code. If you insist on keeping that line you should probably consider clamping Drive_T too so that it won't go higher than 255 in this case.

With a gain of 9 ($0900) the output will be saturated whenver the error is 29 or more (because 29*9=261). To get more resolution I'd probably skip using HPWM and set the CCP module up manually, that way you can 10bit PWM resolution instead of 8.

/Henrik.

richard
- 1st December 2013, 09:59
with a little bit of experimenting you should be able to find the approximate amount of drive needed to maintain your chosen temperature . then use the p_error * kp _value to vary your pwm drive about this point. its best to start with a small kp and increase it till the temp oscillates about your set point . if the load conditions vary substancially however or you wish to vary the set point over a large range you may need use a full pid filter .
ps look up pid in Wikipedia for a good insight

Megahertz
- 1st December 2013, 15:46
Ok, I am actually starting to understand it better now, thanks to all.

I would like to ask, if I use pot to set this gain, the maximum decimal value I will get is 1024 i.e. $0400 (1024/256) which is 4 in terms of Kp. How do I increase Kp if I want to? (If I multiply Kp by 2 or 3 or 4 etc then I start to skip few 2nd decimal digits (pic attached). Any way around it?7166

HenrikOlsson
- 1st December 2013, 16:11
Hi,
Well, you could introduce some oversampling and increase the effective resolution from 10 to say 12 bits. Ie take 40 samples, add them up and divide the result by 10, you now have a 12bit value instead of a 10bit one. Or, you could use two pots, one for coarse and one for fine adjustment.

However, I wouldn't worry too much about dropping a digit after the decimal point. Just do what you we're going to and multiply your ADC value with whatever you need to get into the range that you want, it'll work fine.

/Henrik.

Megahertz
- 1st December 2013, 16:19
Thanks a lot. I now will start with the prop control and add integral and then post the code to discuss any issues.

Aussie Barry
- 1st December 2013, 23:38
If you need to increase the gain greater than 1024 (1024/256 = 4) without losing resolution then simply add 1024 to the ADC pot value (range 1024-2048).
If you still need more gain then add 2048 to the ADC pot value (range 2048 -3072).

I do agree with Henrik though, don't worry too much about dropping a digit after the decimal point.
Perhaps use the multiplication method to quickly get you into the ball park and then use the addition method to fine tune the control if required.
This is the method I used to tune my motor speed controller PID loop.

Cheers
Barry
VK2XBP