PID with Hair Removal

Hi Guys, I am trying to build a PID controller that will run an element connected to an SSR. I used the PID Adaptive Tuning Example as a start point however what I am having issues with is overshoot.

The element is a 200W ceramic element connected to machine aluminium slug. there is enough material there to be able retain heat for a fair amount of time but what I am getting is a huge amount of overshoot.

For instance if i turn the 10K pot up and adjust the set temperature to 119 degrees (or there about) i get an overshoot of 10 or so degrees.

Below is the log of what I am getting as the temperature climbs but i am not sure what I should be adjusting to reduce the overshoot as the temperature climbs.

Any suggestions as to what to tweak would be greatly appreciated as I think i have lost a few more hairs from trying to work this out. The good news however is that once the peak is reached the unit cools back down and sits at the set temperature quit well however I would rather not exceed the set temperature on its way up for this project.

Set Point: 119.36 Thermistor: 116.46 Output :103.56
Set Point: 119.36 Thermistor: 116.46 Output :91.59
Set Point: 119.36 Thermistor: 118.33 Output :92.60
Set Point: 119.36 Thermistor: 118.33 Output :85.61
Set Point: 119.36 Thermistor: 120.33 Output :73.61
Set Point: 119.36 Thermistor: 120.33 Output :59.60
Set Point: 119.36 Thermistor: 121.42 Output :81.59
Set Point: 119.36 Thermistor: 122.45 Output :61.57
Set Point: 119.36 Thermistor: 123.62 Output :55.55
Set Point: 120.33 Thermistor: 124.73 Output :49.52
Set Point: 119.36 Thermistor: 125.98 Output :49.48
Set Point: 119.36 Thermistor: 124.73 Output :37.44
Set Point: 119.36 Thermistor: 127.17 Output :43.39
Set Point: 120.33 Thermistor: 128.40 Output :43.33
Set Point: 119.36 Thermistor: 129.81 Output :32.28
Set Point: 119.36 Thermistor: 129.81 Output :24.22
Set Point: 119.36 Thermistor: 131.15 Output :19.15
Set Point: 119.36 Thermistor: 131.15 Output :26.08
Set Point: 119.36 Thermistor: 132.54 Output :0.00
Set Point: 119.36 Thermistor: 132.54 Output :13.77
Set Point: 120.33 Thermistor: 132.54 Output :0.00
Set Point: 119.36 Thermistor: 134.14 Output :0.00
Set Point: 120.33 Thermistor: 134.14 Output :0.00
Set Point: 120.33 Thermistor: 134.14 Output :0.00
Set Point: 118.33 Thermistor: 134.14 Output :0.00
Set Point: 119.36 Thermistor: 137.25 Output :0.00
#include <PID_v1.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F,16,2);  // set the LCD address for a 16x2 line display

#define PIN_INPUT A0
#define PIN_OUTPUT 3
 
#define ThresholdPin 1             //Analog pin temp pot connected


//Define Variables we'll be connecting to
double Setpoint, Input, Output;

//Define the aggressive and conservative Tuning Parameters
//double aggKp=60, aggKi=0.2, aggKd=2;
//double consKp=1, consKi=0.005, consKd=0.25;

double aggKp=16, aggKi=0.2, aggKd=2;
double consKp=6, consKi=0.005, consKd=0.1;

unsigned long  modelTime, serialTime;

//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint, consKp, consKi, consKd, DIRECT);

double Thermister(int RawADC) {
 double Temp;
 Temp = log(((10240000/RawADC) - 10000));
 Temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * Temp * Temp ))* Temp );
 Temp = Temp - 273.15;            // Convert Kelvin to Celcius
 //Temp = (Temp * 9.0)/ 5.0 + 32.0; // Convert Celcius to Fahrenheit
 return Temp;
}

void setup()
{
  pinMode(PIN_INPUT, INPUT);
  pinMode(PIN_OUTPUT, OUTPUT);
  Serial.begin(57600);
  //initialize the variables we're linked to
  Input = analogRead(PIN_INPUT);
  Setpoint = 900;

  //turn the PID on
  myPID.SetMode(AUTOMATIC);
  
  serialTime = 0;
  
  lcd.init();   // initialize the lcd
  lcd.backlight();
  lcd.clear();
  lcd.setCursor(0,0); //Start at character 0 on line 0
  lcd.print(" SET  TEMP   OUT");
  
}

void loop()
{
  Input = analogRead(PIN_INPUT);
  Setpoint = map(analogRead(ThresholdPin),0,1023,0,1023);
  
  double gap = abs(Setpoint-Input); //distance away from setpoint
  if (gap <= 10)
  {  //we're close to setpoint, use conservative tuning parameters
    myPID.SetTunings(consKp, consKi, consKd);
  }
  else
  {
     //we're far from setpoint, use aggressive tuning parameters
     myPID.SetTunings(aggKp, aggKi, aggKd);
  }

  myPID.Compute();
  analogWrite(PIN_OUTPUT, Output);

  if(millis()>serialTime)
  {
  //lcd.print("SET  TEMP  OUT")
  lcd.print("                ");
  lcd.setCursor(0,1);
  lcd.print(Thermister(Setpoint), 1);
  lcd.setCursor(6,1);
  lcd.print(Thermister(Input), 1); 
//  lcd.setCursor(0,1);

  lcd.setCursor(13,1);
  lcd.print(Output, 1);

  Serial.print("Set Point: ");Serial.print(Thermister(Setpoint), 2); Serial.print(" Thermistor: ");Serial.print(Thermister(Input), 2);  Serial.print(" Output :");Serial.println(Output, 2);  
  serialTime+=1500;
  }
}
double aggKp=16, aggKi=0.2, aggKd=2;
double consKp=6, consKi=0.005, consKd=0.1;

You went with those parameters because?

  if (gap <= 10)
  {  //we're close to setpoint, use conservative tuning parameters

You decided to use two sets of tuning parameters because?

Is an absolute difference of 10 (no units) a good choice?

What disturbances do you expect? Fan unexpectedly blowing cool air over the heater? Ice cold test specimen being dropped on the heater with no warning? Molten iron accidentally dripping from an overhead crucible?

You went with those parameters because?

Initially I used the Autotune and got something close to this, k16, i was 2, d 2 however using those numbers the response time and runaway was a lot worse so I mixed and matched what was in the original example to get closer to what worked.

You decided to use two sets of tuning parameters because?

With a ceramic heating element and a big chunk of aluminium my thinking was that getting it up closer to the temperature faster then stop short and take things a little slower.

I had this set to 200 but reduced this back to the default, then forgot to set it back after tweaking the course pid adjustment.

The head is for melting wax and feeding it in to some molds, I had not actually considered the possibility of using it for injecting pewter in to some of the high temperature molds :slight_smile: Could be well worth looking at that as a future project.

The wax chips are feed in to the back of the unit with a feeder, pushed in to the head and as they go in much like an extruder they are melted allowing the molten wax to come out the end and enter the silicone mold.

At present I melt wax in a container on the stove and pour it in, not an ideal method according to my wife, especially when the kitchen starts smelling of wax.

--- EDIT --

I'll leave the response I just wrote here below the line. But it may be completely off base.

Have a look here: Introducing Proportional On Measurement « Project Blog

It may be that this "proportional on measurment" thingy will instantly fix all your problems.


Ok, so the parameters with which you are initializing your PID need to be tuned for your particular application. This is pretty standard.

First step - is there documentation? Yes - it's here: http://playground.arduino.cc/Code/PIDLibrary . Cool banannas. But, it's frankly not very helpful.

A PID controller has three parameters:

p - the proportional parameter. Too weak and the output will rise too slowly. To strong, and the output willoscilate.
d - the derivative parameter. Helps stop the output oscilating. Too great, and the output will be overdamped.
i - the integral parameter. Provides some overshoot. this allows the output to rise quickly when the target is far from the desired value.

First, is PID suitable for your application at all? PID is only suitable when the output is analog. Now, you have an SSR set up which presumably can switch at arduino PWM speed. But does it actually work with our heating element? That is - will an analog out of 128 properly drive your heater at half value? If your element is either on or off full, then PID will get you nowhere.

Now, I personally haven't use a PID controller. But as I understand it, your tune it like this:

But if that's ok, then the thing to do is to set d and i to zero and to play with p. If p is too small, the output will oscillate. If it is too large, then the output will either be 100% on or 100% off above and below your setpoint. You want to adjust it so that you have a small amount of oscilation.

The d parameter damps the oscilation. You want to bring it up until the oscilation stops.

At this point, your PID will find the target, but it will take a long time because the system is damped. The i parameter provides overshoot, which helps your system get up to the correct value quickly. You want to bring this up until the amount of overshoot is something you can live with.

If the overshoot is too great - reduce the damping or increase p. And so on. And you want to do this for a range of setpoints.

Only thing I'd suggest is to keep some sort of recode if the settings that worked reasonably well. Otherwise, you can wind navigating to a place where the paramters are completely wrong and have no easy way to get back to where you were.

vangalvin:
With a ceramic heating element and a big chunk of aluminium my thinking was that getting it up closer to the temperature faster then stop short and take things a little slower.

That is exactly how a well tuned PID loop works with just one set of parameters. Get rid of the "Adaptive Tuning" until you have an actual reason to include it.

Thanks @PaulMurrayCbr I just checked the SSR and it seems to be working well with the PWM output of the arduino. I will have a bit more of a read of the link you sent and see if i can work out how to tweak things back to prevent the overshoot.

@Coding Badly I will remove the “Adaptive Tuning” and see how that goes, I also re-ran the autotune example and ended up with the following results…
pp=0.49, i=0.01, d=0.00

And remember the power dissipated in a resistor varies with the SQUARE of voltage so if volts are doubled power is increased 4 times, if volts is halved, power falls to 1/4, something to think about if your controller is regulating voltage instead or current.

edgemoron:
And remember the power dissipated in a resistor varies with the SQUARE of voltage so if volts are doubled power is increased 4 times, if volts is halved, power falls to 1/4, something to think about if your controller is regulating voltage instead or current.

I had not considered that, The element I have is a 240V AC 300Watt ceramic element. Looking up the specs on the SSR it would appear that I ordered the wrong one and have ended up with one that is Zero Crossing but only handles and On/Off at a set level. On voltage is 2.4v and it has a switching speed of only 10ms. This could be contributing to some of my problems.

Hi,
Where is the thermistor positioned with respect to the heating element.
If it only over shoots on warm up, it sounds like the thermistor is not close enough to the element.

On warm up you may have a temperature gradient (difference) between thermistor and element.
When the thermistor gets to your setpoint, the element is at a higher temp, so it soaks through when the element is switched off.

Once everything is at working temperature, you do not have a gradient.

Tom... :slight_smile:

edgemoron:
And remember the power dissipated in a resistor varies with the SQUARE of voltage so if volts are doubled power is increased 4 times, if volts is halved, power falls to 1/4, something to think about if your controller is regulating voltage instead or current.

Same issue if you control current:

P = i^2 * r
P = v^2 / r

OP, have you considered a simple bang-bang temperature control? It works pretty well for your house's thermostat and is unconditionally stable.

TomGeorge:
Hi,
Where is the thermistor positioned with respect to the heating element.
If it only over shoots on warm up, it sounds like the thermistor is not close enough to the element.

Attached is a chart showing what I am geting
Blue is the Set Temperature
Red is the Thermistor
Green is the Output

It was stable then I hit the head with some spray nitrogen to drop the temperature, As you can see it over compensated quite a bit.

Also attached is a photo of the element with the thermistor attached. the thermistor is about 15mm deep in to the aluminium.

gfvalvo:
OP, have you considered a simple bang-bang temperature control? It works pretty well for your house's thermostat and is unconditionally stable.

I had considered that :slight_smile: Then someones said.. Why don't you use a PID and having never used it before I thought.. Hey lets give it a crack. Temperature of the wax is kind of critical, Too cold and it will not adhere to itself in the mold. To hot and it ends up with a kind of crystalline structure. I am not 100% sure but think it has some form of plastaciser in it that separates out if the heat gets too high.

What happens then is the surface ends up quite rough.

Hi,
You are using analogWrite to control your SSR.

Won't work the way you think, you need phase control to give you variable element power.

The element is either ON or OFF.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Thanks.. Tom.. :slight_smile:

The analog output will PWM the SSR and heater. Thermal mass will provide a low pass filter effect. So, it's essentially analog control. Just like if you connect an LED to a PWM output. It's just going on and off. But the LPF effect of your eyes make it look like you're changing the brightness.

Hi,
To check your output control you need to write a very simple code.

Code would use your set pot and directly control the analogWrite, serial print the analogWrite value and monitor the voltage across the element.
(You will need to divide the pot output by 4 as to scale the variable for the analogWrite.)

Then note the serial value vs voltage across the element.

Tom.. :slight_smile:

Hi,

gfvalvo:
The analog output will PWM the SSR and heater.

No it won't, the SSR is conducting a 50 or 60Hz AC current.
The PWM from pin3 is 490Hz.
The SSR has a triac in it, once its switched ON it will not turn OFF until the AC Current drops to zero.
This is up to 10mS or 8mS later.
490Hz is expecting the SSR to respond in 1/490 = 2mS
The 490Hz will in no way be synced to the 50 or 60Hz
You cannot switch an SSR On and Off at 490Hz with variable duty cycle.
Tom.. :slight_smile:

Dooh, I was thinking DC.

TomGeorge:
Hi,No it won't, the SSR is conducting a 50 or 60Hz AC current.
The PWM from pin3 is 490Hz.
The SSR has a triac in it, once its switched ON it will not turn OFF until the AC Current drops to zero.
This is up to 10mS or 8mS later.
490Hz is expecting the SSR to respond in 1/490 = 2mS
The 490Hz will in no way be synced to the 50 or 60Hz
You cannot switch an SSR On and Off at 490Hz with variable duty cycle.
Tom.. :slight_smile:

So, you'd have to filter the output of the PWM signal to provide something that looks ... no, that wouldn't work either: an SSR is either on or off. Maybe a nice high power MOSFET? With some filtering over the output so that the heating element doesn't see the PWM frwquency?

TomGeorge:
Hi,
You are using analogWrite to control your SSR.

Won’t work the way you think, you need phase control to give you variable element power.

The element is either ON or OFF.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Yes, starting to think I may need to make an opto-isolated SCR circut for this instead of using a SSR unless as has been suggested i use Bang Bang control or capture the output and use that to slam the SSR on and off.

Please excuse the drawing. it should give you an idea as to what and how I have things set up.