PID library only outputs min or max value, but not a varying PWM

So I’m working with the PID library and I’m having some issues. For some reason the output is writing essentially a “high” or “low”(it alternates between the min and max values that I set, if I use the default it just alternates between 0 and 255) without actually adjusting the PWM value between them.

I’ll post a picture of the serial monitor as well so you can see what I mean. I know my code is kind of a mess and its labelled, but its pretty much just the basic PID example with a few added things.

#include <PID_v1.h>

#define PIN_INPUT A1
#define PIN_OUTPUT 9



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

//Specify the links and initial tuning parameters
double Kp=2, Ki=5, Kd=1;
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);




void setup() {

 
  
 
  pinMode(PIN_INPUT, INPUT);
  pinMode(PIN_OUTPUT, OUTPUT);

  Serial.begin(9600);



  // PID

 //initialize the variables we're linked to
  //Input = analogRead(PIN_INPUT);
  Setpoint = 1000;

  //turn the PID on
  myPID.SetMode(AUTOMATIC);
  
  
}

void loop() {

 
  
  


  Input = analogRead(PIN_INPUT);
  myPID.Compute();
  analogWrite(9, Output);

 Serial.print("\t");
 Serial.println(analogRead(A1));
 Serial.print(Output);
 delay(10);
 

  
}

Screen Shot 2016-06-23 at 9.32.52 PM.png

How is this wired? What are you controlling?

I'm trying to set up a temperature controller for a small heat element. The temperature is being measured with an opamp configured as a differential amplifier reading the voltage before and after the element. The readings look pretty good, and if I put a constant current through the coil, I can read the change in resistance as it heats up. One issue here that may be causing this is that it only reads when current is applied to the heat element, otherwise it just reads 0.

I'm trying to feed the resistance reading into the PID controller and vary a PWM output.

I hope that makes sense

And how does the PWM output drives the coil?

double Kp=2, Ki=5, Kd=1;

A quick check with an online PID simulator reveals ... Wowsers! Those parameters are seriously unstable.

Why don't you start with just a bit of P?

through a transistor driver. I can heat the coil fine, and read the temp fine, I just need the PWM to control the temperature.

Really? interesting! Those are the values that are in the arduino example for the basic setup. Can you make any recommendation for those? If P is set at two isn't that pretty low? I guess I don't fully understand how it responds to those.

mdlockyer77: Those are the values that are in the arduino example for the basic setup.

Your point being?

Can you make any recommendation for those?

Yes. Start with a low value for P (0.1 comes to mind) and zero for the other two. The response should be very sluggish. At that point you know the software and hardware are functioning correctly.

Beyond that, you are going to have to learn to tune. There are no magic parameters. The parameters depend entirely on your particular hardware and goals.

Will try it now. Thanks!

Hi again - looks like you are not too sure about the theory behind PID and importance of the values for Kp, Ki, Kd which drives behavior of convergence of the output. They really depend on the system you are trying to control and its intrinsic parameters. Temperature does not evolve (at least with what we play with) in ms time - more with seconds or minutes depending on the inertia of your "radiator" whereas the drift created by a sudden wind change on position of an airplane flying quick or a fast car skidding on ice (controlling direction to desired trajectory in both cases) dictates very fast response time without overshoots.

Without willing to sound professoral, I would suggest you do yourself a big favor and watch that video on the concepts behind PID (he has a couple more really good to watch too) and then read the details of the algorithm for the PID library and how the developer got there. He is making a great case on how systems react on perturbations and how it gets to the desired output esp in an environment where you have constraints on the values (min/max) you can play with (0-255 or 0-1023 on your arduino's pins for example).

Last watch that short video which discusses the different types of system you can choose (P, PI, PID or more rarely PD).

Understanding how the coefficients used in the sums of treatment on the errors for the Proportional, Integral, and Derivative terms play is key in determining how you want to set them up.

P accounts for present values of the error. For example, if the error is large and positive, the control output will also be large and positive. I accounts for past values of the error. For example, if the current output is not sufficiently strong, error will accumulate over time, and the controller will respond by applying a stronger action. D accounts for possible future values of the error, based on its current rate of change.

selecting wrong values means your system will likely overshoot a setpoint or enter long oscillations before reaching the set point.

I'm a bit curious also of your use of PWM (which basically is setting 0 and 5V output very quickly into your system. The average value of voltage and current fed to the load is controlled by turning the switch between supply and load on and off at a fast rate. The longer the switch is on compared to the off periods, the higher the total power supplied to the load and its main use is to allow the control of the power supplied to electrical devices, especially to inertial loads such as motors.

What bugs me in your set up is that your transistor driver is probably very fast and reacting to ON/OFF orders delivered through PWM. Indeed PWM is not delivering say 2.5v so that you adjust the output power delivered to your coil to 50%, it does deliver 0V or 5V and thus turning on and off full power to your coil. As you rightly noticed, you currently rely on having access to power to measure your temperature. What I wonder is that you are probably reading through your OP-AMP differential amplifier weird values and totally confusing the PID algorithm which will think that current modification of guidance did not deliver anything (will think "wow temperature is still zero, better heat that thing way more") so will quickly overshoot to max value and then notice "wow it's way too warm too quickly" and switch off.

You should probably read temperature either with a MLX 90614 (infrared, don't need to touch the surface) or DS18B20 for example if you can safely establish contact with the warm surface.

hope this helps.

Thank you for the info! It is much appreciated.

I'm not sure if its going to work well, but the way I have it set up the PWM passes through an RC filter before going into the opamp to convert it to a voltage.

I will watch all the videos on PID now. Thanks again!

...ultimately to a resistive heating element?

mdlockyer77: ... I'm not sure if its going to work well, but the way I have it set up the PWM passes through an RC filter before going into the opamp to convert it to a voltage. ...

I'm not sure either to say the least :)