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)