PID Relay Temperature Control having Issue

I am attempting to hack an old vacuum oven by adding a PID control using a relay. (My code is based on this: Arduino Playground - PIDLibraryRelayOutputExample) The PID output is supposed to range between 0 and 5000, which corresponds to the time, within a 5000 ms window, for which the relay will turn on the oven. My issue is that no matter which constants I use, the PID output remains at 100% and stays on after the set temperature has been reached. The oven's temperature itself tends to coast an additional 10 or more degrees after the heating elements are turned off so, ideally, I'd think we'd want the output to decrease as we approach the setpoint. Any help would be appreciated, and the code is below.

#include <math.h>
#include <SPI.h>
#include <PID_v1.h>
#include <LiquidCrystal.h>    
LiquidCrystal lcd(7, 6, 5, 4, 3, 2); 
 
 
#define MAX6675_CS   10
#define MAX6675_SO   12
#define MAX6675_SCK  13
#define RelayPin 11

//Define Variables we'll be connecting to
double Set_temp, Input, Output;
double kp = 2;
double ki = 5;
double kd = 1;

//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Set_temp, kp, ki, kd, DIRECT);

int WindowSize = 5000;
unsigned long windowStartTime;
 
void setup() 
{
  lcd.begin(16,2);
   Serial.begin(9600);
pinMode(RelayPin, OUTPUT);

  windowStartTime = millis();

  //initialize the variables we're linked to
  Set_temp = 60;

  //tell the PID to range between 0 and the full window size
  myPID.SetOutputLimits(0, WindowSize);

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

}

//For the normally open relay configuration, the oven is connected to the COM and NO pins of the relay. A HIGH signal will close the circuit and operate the oven.
//For the normally closed relay configurations, the oven is connected to the COM and NC pins of the relay. A LOW signal will close the circuit and operate the oven.

void loop() {
  double temperature_read = readThermocouple();  
  Input = temperature_read;                                                             
myPID.Compute();
//  /************************************************
//     turn the output pin on/off based on pid output
//   ************************************************/

  lcd.setCursor(0,0);
  lcd.print("TEMPERATURE");
  lcd.setCursor(7,1);  
  lcd.print(temperature_read,1);    
  delay(1000);

unsigned long now = millis();
if (now - windowStartTime > WindowSize)
{ //time to shift the Relay Window
windowStartTime += WindowSize;
}
if (Output > now - windowStartTime) digitalWrite(RelayPin, HIGH);
else digitalWrite(RelayPin, LOW); 

Serial.print(millis()); 
Serial.print(","); 
Serial.print(Input); 
Serial.print(","); 
Serial.print(Output); 
Serial.print(","); 
Serial.println();;

}
// make temperature adjustments here

double readThermocouple() {

  uint16_t v;
  pinMode(MAX6675_CS, OUTPUT);
  pinMode(MAX6675_SO, INPUT);
  pinMode(MAX6675_SCK, OUTPUT);
  
  digitalWrite(MAX6675_CS, LOW);
  delay(1);

  // Read in 16 bits,
  //  15    = 0 always
  //  14..2 = 0.25 degree counts MSB First
  //  2     = 1 if thermocouple is open circuit  
  //  1..0  = uninteresting status
  
  v = shiftIn(MAX6675_SO, MAX6675_SCK, MSBFIRST);
  v <<= 8;
  v |= shiftIn(MAX6675_SO, MAX6675_SCK, MSBFIRST);
  
  digitalWrite(MAX6675_CS, HIGH);
  if (v & 0x4) 
  {    
    // Bit 2 indicates if the thermocouple is disconnected
    return NAN;     
  }

  // The lower three bits (0,1,2) are discarded status bits
  v >>= 3;

  // The remaining bits are the number of 0.25 degree (C) counts
  return v*0.25;
}

Your post was MOVED to it's current location as it is more suitable.

Could you also take a few moments to Learn How To Use The Forum.

Other general help and troubleshooting advice can be found here.
It will help you get the best out of the forum in the future.

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