0

I am designing a PID temperature controler; as far as I managed to write it so far, you find the code below.

Can you please help me check if Integrator wind up and other PID elements are configured please?

When i run the code at some point close to the set point , it starts behaving like an ON and OFF code

I don't know if this is a valid question but im asking it anyways .

and if you can make any edits . i will be glad to check them out

// programing the pid
const int pin = 3;  // PWM analog output 
double cumerror = 0; // Initialising the cumulator of the integrator to 0

double input, setpoint, integral, proportional, piderror, pidvalue;

// Input values
double kp = 25; // seting proportional at 25
double ki = 0;  // seting the integral at 0

void setup() {
  setpoint = 37; // seting the setpoint at 37
  Serial.begin(9600);
}

void loop() {
  double inputvalue = map(analogRead(A0), 0, 1023, 0,
                          100); // reading the values from the analog signals
                                // and mapping it to a 100 deg scale

  piderror = setpoint - inputvalue; // calculating the error

  // calculating the integral ((Naturally ki= cumerror *dt), we do not have to
  // multiply by dt, since dt = 0 because i am using the sample time delay(1000)
  // every time )
  cumerror += piderror;
  integral = ki * cumerror;

  // calculating the proportional error

  proportional = kp * piderror; // calculating the proportional error

  // changing the P and I parameters as the error approaches the set point
  if (3 < piderror < 10) {

    kp = 10;
    ki = 0.5;
    cumerror += (1 * piderror);
    integral = ki * cumerror;
  }
  // Making the parameters =0 as the error approaches more 0

  if (piderror < 3) {
    proportional = 0;
    pidvalue = 0;
    integral = 0;
  }

  pidvalue = proportional + integral;

  if (pidvalue <= 0) {
    pidvalue = 0;
  }

  if (pidvalue > 255) {
    pidvalue = 255;
  }

  analogWrite(pin, pidvalue); // sending the pid value to the heater

  delay(1000);
  
  cumerror=cumerror;
}
  • 1
    Where are your design specs? > Max Temp. rate of change expected. load profile, error tolerance, resolution, step change overshoot? – Tony Stewart EE75 Jul 14 '20 at 16:48
  • 1
    Maybe you could explain what you are trying to implement rather than dumping the code. You have a PI controller with no antiwindup and are doing some weird stuff near the setpoint is what I make of it. – Spehro Pefhany Jul 14 '20 at 17:03
  • Your code is poorly formatted, making it difficult to read and difficult to debug. Please [edit] to fix that first. Indent it properly and consistently. Remove blank lines within a section unless they are required for clarity. Remove all the `Serial.print()` lines as they (should) have no affect on the operation - unless you suspect there is a problem there (in which case you should explain why you think there is a problem or why we need to see them). Remove spaces before punctuation `,` or `;` and add spaces after punctuation for legibility and clarity. i.e, Make it look professional. – Transistor Jul 14 '20 at 17:11
  • Marcus has tidied the code for you. Why are you manipulating the P constant based on the value of *piderror*? – Transistor Jul 14 '20 at 17:32
  • @Transistor , yeah , because i am assuming as the temperature approaches the set value , to reduce te PID error , i should reduce both P and I – Kabera David Jul 14 '20 at 17:35
  • But i am trying to Find how, to insert an anti windup integrator so as to not make it an On and OFF , switch as the temperature approaches is at the set value or approaches the set value. – Kabera David Jul 14 '20 at 17:37
  • Read [Understanding PI control](https://electronics.stackexchange.com/questions/346730/understanding-the-flow-of-a-pi-controller/346759?r=SearchResults&s=2|40.1510#346759) first. You are missing some fundamental understanding of PID control. Your ON/OFF control problems are due to incorrect tuning of a properly coded controller (but your's isn't properly coded). – Transistor Jul 14 '20 at 17:47
  • @KaberaDavid Is the temperature measurement and the heater coil(?) **located close to each other ?** If your actuator* and sensor are not *co-located*, the delay from actuation* to sensing can make your closed loop system unstable. – AJN Jul 15 '20 at 01:56
  • `delay(1000);` The value of this delay should have been calculated based on the speed of thermal response. If the system heats up quickly, the temperature would have overshot the target in `1000ms`, leading to an ON-OFF type response. – AJN Jul 15 '20 at 01:59
  • @AJN The temperature sensor is next to the process , ( a metal placed on top of a heater ), but how do i calculate the thermal response ? , is it puting the heater on power supply and calculate the amount of time it takes to change from for example 0 deg to 10 deg ? – Kabera David Jul 15 '20 at 05:20
  • `is it putting the heater on power supply and calculate the amount of time it takes to change from for example 0 deg to 10 deg ?` This is what we would call a *step response*. It will give you an idea what delay to use and how big/small your `Kp` should be. How did you arrive at the current values of `Kp`, `Kd` and `Ki` ? trial and error ? It will be good if you can post a graph of the controller output and sensor input waveforms here. Also a step response as you indicated above. As mentioned by others, start with simple `Kp` alone. `Ki` and gain switching etc can be implemented later. – AJN Jul 15 '20 at 05:56
  • @AJN do you mean that there is no use of the integrator ? and anti windup reset from the integrator on this project – Kabera David Jul 15 '20 at 07:37
  • As mentioned in the currently posted answer and the comments, try to get the system stabilised with proportional control alone. If the temperature difference in steady state is beyond the specification, then introduce the integral term. Introduce the anti wind-up afterwards, if the integrator state goes to large values. Debugging the setup will be easier if you introduce the features one by one. – AJN Jul 15 '20 at 07:54
  • @AJN ahh ok yeah i understand what you mean – Kabera David Jul 15 '20 at 07:58

1 Answers1

1

KP, KI and KD are usually fixed and not manipulated based on the error as you are doing. Instead try and get the controller working as P-only.

Try reducing it to this and get P-only control working properly: -

piderror = setpoint - inputvalue;
proportional = kp * piderror; 
pidvalue = proportional + integral;
if (pidvalue <= 0) {
  pidvalue = 0;
}
if (pidvalue > 255) {
  pidvalue = 255;
}
analogWrite(pin, pidvalue);

Start with a much gentler KP - maybe 1 or 2, try it out and report back. Plot a graph if you can and edit it into your question. We'll proceed from there.

Transistor
  • 168,990
  • 12
  • 186
  • 385