PID help needed

Hi. My project aims to implement a PID temperature control to run a heating element, using a thermistor (NTC 100k) for sensing in A0. The heating element is controled by Arduino's pin 13 using a D4184 MOSFET module to command its connection to a power supply. I'm using two libraries for the code: ArduPID and SmoothThermistor. The problem is that I can't get a control loop going, the heating element temperature just shoots straight up.

  • I have tried other code as well, replacing the "SmoothThermistor" library by various Steinhart-Hart calculation codes I found on the internet. But same outcome as before.
  • I'm aware that there are other PID libraries as well, but the one I'm using seems the most user-friendly of them all.
  • I've seen posts on this forum about PID "troubles" but didn't help.

This problem arises from the PID k values? Tried many. Or is something else going on? I can't get around this. Please help.

Thanks for your time.

Libraries:

Thermistor wiring (100k Thermistor and 100k Resistor):

Code:

#define THERMISTOR_PIN A0
#define DIGITAL_CONTROL_PIN 13

#include <SmoothThermistor.h>
//SmoothThermistor smoothThermistor(THERMISTOR_PIN, ADC_SIZE_10_BIT, THERMISTOR, RESISTOR, BETA COEF, NOMINAL RESISTANCE, SAMPLES);
  SmoothThermistor smoothThermistor(THERMISTOR_PIN, ADC_SIZE_10_BIT, 100000,     100000,   3950,      25,                 10);

#include "ArduPID.h"
ArduPID myController;
double PID_setpoint = 80;
double PID_input, PID_output;
double p = 0.9;
double i = 0.3;
double d = 0.1;

void setup(void) {

	Serial.begin(9600);
	myController.begin(&PID_input, &PID_output, &PID_setpoint, p, i, d);
}

void loop(void) {

	PID_input= analogRead(THERMISTOR_PIN);
	myController.compute();
	analogWrite(DIGITAL_CONTROL_PIN, PID_output);

	// Serial Plotter
	Serial.print(setpoint);
	Serial.print(",");
	Serial.println(smoothThermistor.temperature());
}

Try:

int input = analogRead(THERMISTOR_PIN); // I changed my mind... 0 - 1023 analog input

float input = analogRead(THERMISTOR_PIN); oops... sorry for the edit.

Actually

float input = smoothThermistor.temperature();

is probably what's needed.

Thanks for your help.

Already tried input = smoothThermistor.temperature(); to no avail.

input = THERMISTOR_PIN; Was a mistake I made tidying up the code to copy it here. Fixed it:

input = analogRead(THERMISTOR_PIN);

Thanks

Your input variable is PID_input but you never update the value so why do you think the output will change?

The same is true for PID_output which never gets applied to your- output. Also, Pin 13 does not support PWM so analogWrite() does not work on that pin.

cedarlakeinstruments, double is used as the ArduPID library requests it

Oh you are godsend. Right, its not a PWM a pin. Thank you.

original example:

#include "ArduPID.h"

ArduPID myController;

double **input**;
double output;

// Arbitrary setpoint and gains - adjust these as fit for your project:
double setpoint = 512;
double p = 10;
double i = 1;
double d = 0.5;

void setup()
{
  Serial.begin(115200);
  myController.begin(&**input**, &output, &setpoint, p, i, d);

  // myController.reverse()               // Uncomment if controller output is "reversed"
  // myController.setSampleTime(10);      // OPTIONAL - will ensure at least 10ms have past between successful compute() calls
  myController.setOutputLimits(0, 255);
  myController.setBias(255.0 / 2.0);
  myController.setWindUpLimits(-10, 10); // Groth bounds for the integral term to prevent integral wind-up
  
  myController.start();
  // myController.reset();               // Used for resetting the I and D terms - only use this if you know what you're doing
  // myController.stop();                // Turn off the PID controller (compute() will not do anything until start() is called)
}

void loop()
{
  **input** = analogRead(A0); // Replace with sensor feedback

  myController.compute();
  myController.debug(&Serial, "myController", PRINT_INPUT    | // Can include or comment out any of these terms to print
                                              PRINT_OUTPUT   | // in the Serial plotter
                                              PRINT_SETPOINT |
                                              PRINT_BIAS     |
                                              PRINT_P        |
                                              PRINT_I        |
                                              PRINT_D);
  
  analogWrite(3, output); // Replace with plant control signal
}

Thanks for your feedback. You are right pointing out that mistake, I made a clumsy job pasting the code here (fixed it). The code used by my Arduino didn't have that error.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.