Ciao a tutti, sto cercando di realizzare un sistema di controllo di temperatura basandomi su una resistenza elettrica, un termistore MAX6675 e un SSR 40 DA. L’obiettivo che vorrei raggiungere è simile a quello che fa l’hotend di una stampante 3D, mantenendo una temperatura discretamente stabile. Sono partito dall’esempio “PID_RelayOutput.ino” che trovate all’interno della libreria PID Arduino Library.
Attualmente il mio codice è questo:
#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);
Il problema è che la lettura del valore dal MAXX6675 sembra andare in conflitto con “Input = thermocouple.readCelsius();” nel void loop. Questo dovrebbe far leggere alla libreria PID il valore dal termistore. Il valore diventa fisso e ovviamente il tutto smette di funzionare immediatamente.
Probabilmente il mio approccio è completamente sbagliato, non ne ho idea, è la prima volta che mi cimento nel PID e onestamente sto trovando la documentazione davvero difficile da comprendere.
Un altro problema è che se la temperatura è molto bassa l’ssr non viene neanche attivato.
Per chi volesse dare un occhiata carico negli allegati un file zip con tutto il progetto.
PID_MAX6675_SSR.zip (17.2 KB)