MAX6675 PID Thermostat

Hello everyone, i’m trying to do a system for controlling a heat resistence with a thermistor MAX6675 and a Solid State Relay “SSR 40 DA”. What i have in mind is like a 3D Printer Hotend control, so after a calibration i can keep a decent temperature hold starting from the one i’ve set on the project. I started from the “PID_RelayOutput.ino” example you can find in PID Arduino Library.

Now my code looks like this:

#include <PID_v1.h>
#include <max6675.h>
#include "thermocouples.h"
#include "hold.h"

#define RELAY_PIN 6

//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);

int WindowSize = 5000;
unsigned long windowStartTime;

void setup()
{
  Serial.begin(9600);
  pinMode(RELAY_PIN, OUTPUT);
  windowStartTime = millis();

  //initialize the variables we're linked to
  Setpoint = 150;

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

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

void loop()
{
  serial.Update();
  Input = thermocouple.readCelsius();
  myPID.Compute();

  /************************************************
   * turn the output pin on/off based on pid output
   ************************************************/
  if (millis() - windowStartTime > WindowSize)
  { //time to shift the Relay Window
    windowStartTime += WindowSize;
  }
  if (Output < millis() - windowStartTime) digitalWrite(RELAY_PIN, HIGH);
  else digitalWrite(RELAY_PIN, LOW);
  
}

“hold.h”

double MAXREAD = thermocouple.readCelsius();

class Hold
{
  // Class Member Variables
  // These are initialized at startup
  long OnTime;     // milliseconds of on-time
  long Wait;    // milliseconds of off-time
 
  // These maintain the current state
  int state;                 // ledState used to set the LED
  unsigned long previousMillis;   // will store last time LED was updated
 
  // Constructor - creates a Hold 
  // and initializes the member variables and state
  public:
  Hold(long on, long off)
  {
  OnTime = on;
  Wait = off;
  
  state = LOW; 
  previousMillis = 0;
  }
 
  void Update()
  {
    // check to see if it's time to change the state of the LED
    unsigned long currentMillis = millis();
     
    if((state == HIGH) && (currentMillis - previousMillis >= OnTime))
    {
      state = LOW;  // Turn it off
      previousMillis = currentMillis;  // Remember the time
      MAXREAD = thermocouple.readCelsius();
      Serial.println(MAXREAD);
      MAXREAD = 0;
    }
    else if ((state == LOW) && (currentMillis - previousMillis >= Wait))
    {
      state = HIGH;  // turn it on
      previousMillis = currentMillis;   // Remember the time
    }
  }
};
 
 
Hold serial(50, 1000);

“thermocouples.h”

// Termocouple 1
int DO1 = 2;
int CS1 = 3;
int CLK1 = 4;

MAX6675 thermocouple(CLK1, CS1, DO1);

The problem is that the value read from the MAX6675 seems to be in conflict with the “Input = thermocouple.readCelsius();” in void loop. This is supposed to make the PID library read the value from the Thermistor. The value seems to become fixed and of course anything works anymore.

Maybe my approach to this is totally wrong, i have no idea, is the first time that i play around with PID and honestly i’m finding the documentation really hard to understand.

Plus another thing is that if the temperature is low (like 30° C) the heater element doesn’t fire at all.

If you want to take a look i’m putting in attachments the full project zip file.

PID_MAX6675_SSR.zip (17.2 KB)

What's your problem? "The value seems to become fixed and of course anything works anymore." Is a typo in this sentence? I'm not an native English speaker but it sounds wrong to me. If you think it's correct please explain what it means.

I guess you should describe what you expect your sketch to do. I think it's quite strange to check if a temperature value is smaller than a time range. Your Hold class doesn't seem to do anything and why is it called serial? You know that there is an object Serial which does something completely different? Do you think this naming is clever?