Go Down

Topic: PID temp controller, temp stop raising or raising very slow before taget ? (Read 1 time) previous topic - next topic


I'm trying to regulate temp in a pot of water with a PID controller build on arduino uno. My problem is, that when I get very close to target (60 C) the temp stop raising or or it's raising very slow, so that I never get to target.

The pot sits on a single electrical stove controlled by a SSR relay. It takes a long time from heat is turned on until there is a reaction, and when the element is turned of it'll keep heating for a while. Water is circulated and temp is measured in the outflow from the pot with a dallas DS18B20 digital sensor.

I hope you can give me some feedback. Did I miss something out

My code is more or less taken from the pid example on this page.

Code: [Select]

#include <OneWire.h>
#include <DallasTemperature.h>
#include <PID_v1.h>
//#include <PID_AutoTune_v0.h>

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

PID myPID(&Input, &Output, &Setpoint,5000,0,0, DIRECT); //Specify the links and initial tuning parameters

int WindowSize = 3000;
unsigned long windowStartTime;

OneWire oneWire(2); // Setup a oneWire instance to communicate with any OneWire devices
DallasTemperature sensors(&oneWire); // Pass our oneWire reference to Dallas Temperature.
DeviceAddress insideThermometer = { 0x28, 0x9E, 0x1B, 0xBD, 0x04, 0x00, 0x00, 0x22 }; // Assign the addresses of your 1-Wire temp sensors.

void setup(void)
  pinMode(7, OUTPUT); // pinMode test

  Serial.begin(9600); // start serial port
  sensors.begin(); // Start up the library
  sensors.setResolution(insideThermometer, 10); // set the resolution to 10 bit (good enough?)

  windowStartTime = millis();
  Setpoint =60 ;  //initialize the variables we're linked to
  myPID.SetOutputLimits(0, WindowSize);  //tell the PID to range between 0 and the full window size
  myPID.SetMode(AUTOMATIC);  //turn the PID on

void loop(void)
  Input = sensors.getTempC(insideThermometer);

  unsigned long now = millis();

  if(now - windowStartTime > WindowSize)
  { //time to shift the Relay Window
    windowStartTime += WindowSize;

  if(Output > now - windowStartTime)
    digitalWrite(7, HIGH);
    digitalWrite(7, LOW);


Looks like you need to use the Ki component too. I'm not sure what the PID's doing for you if you're only going to use the Kp component. Maybe take a look at the autotune library too.


Hi, I'm not familiar  with this PID program, but if it has AUTOTUNE have you used it.
This will help get yor PID parameters setup, what you are experiencing is a classic, OFFSET ERROR, adjusting the PID params will fix this.
But try AUTOTUNE first so that you are in the right ball park and you will not have to make large changes to parameters, which interact with each other.

Tom..  :)

Start AUTOTUNE with the pot and water at room temperature, this is essential to get tuning right.
Everything runs on smoke, let the smoke out, it stops running....


I tried to set a higher Ki but i did not have time to let run long enough to know the effect. About autotune. I tryed to implement it, but it didn't seam to work. Nothing happened for a long time. I'll try again.

Would it make it, if I put
PID_ATune aTune(&input, &output);"
before setup

in the beginning of loop
and print aTune.GetKp() in the loop to see if any values have been calculated?

That's what I did, and it didn't seam to work.


Your mileage may vary, but in my view it is better to understand the concepts behind the PID algorithm and tune it by hand at least a couple of times before handing that responsibility over to an autotune library. The symptoms of the problem indicate that the gain of the integral component is insufficient and once you'd got your head around the algorithm that will be obvious. It's also only a few seconds work to adjust. It'll need some experimenting to figure out the appropriate parameters for your system but the method of working them out by trial and error is well known and easy to follow.


a PID is too fast for this.
if temp <  setpoint-0.1  switch on heater for 1 second.
wait 1 second
if temp < setpoint-0.5 switch on heater for 5 seconds
wait 1 second
above in a calc method
so Ppart = (setpoint - temparture)*Kp
this is only Kp used start with 10

calculating from the Ipart= (setpoint-temperature)*Ki+ipart
ontime is Ppart+Ipart
wait 1 second and do this loop again
paul deelen
making controls with codesys PLC and arduino


Wildbill is right, you need the Ki component if you want it to actually reach the target temperature. When it starts overshooting the target temperature, you know that Ki is too high.
Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

Go Up