Arduino Nano PID Control

Hello, I have the attached schematic and the code below.

I don't know for sure if the code is correct, I just checked it and it seems to work, but I need your advice.
Please have a look at the code and tell me what you think.

#include <LiquidCrystal.h>
#include <SPI.h>
#include <Wire.h>
#include <max6675.h>
#include <PID_v1.h>

#define thermoDO 12
#define thermoCS 10
#define thermoCLK 13
#define potentiometer A0
#define zerocrossing 2
#define triac 7
#define relay A1

float realTemperature; 
int pottemperature;

int duty = 0;
int counter = 0;
int tempError = false;  // global error flag
int shownError = false; //flag to say error shown

LiquidCrystal lcd(3, 4, 5, 6, 8, 9);

byte thermometer[8] = //icon for termometer
{
  B00100,
  B01010,
  B01010,
  B01110,
  B01110,
  B11111,
  B11111,
  B01110
};

byte arrow[8] = //icon for arrow
{
  B11000,
  B01100,
  B00110,
  B00011,
  B00011,
  B00110,
  B01100,
  B11000
};

MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);

/*  The circuit:
   LCD RS pin to digital pin 12
   LCD Enable pin to digital pin 11
   LCD D4 pin to digital pin 5
   LCD D5 pin to digital pin 4
   LCD D6 pin to digital pin 3
   LCD D7 pin to digital pin 2
   LCD R/W pin to ground
   LCD VSS pin to ground
   LCD VCC pin to 5V
   10K resistor:
   ends to +5V and ground
   wiper to LCD VO pin (pin 3)
*/

volatile int pidOut = 0;

double Setpoint, Input, Output;
double aggKp = 4, aggKi = 0.2, aggKd = 1;
double consKp = 1, consKi = 0.05, consKd = 0.25;
PID myPID(&Input, &Output, &Setpoint, consKp, consKi, consKd, DIRECT);

void setup() {
  lcd.begin(16, 2);
  lcd.createChar(0, thermometer);
  lcd.createChar(1, arrow);
  lcd.setCursor(0, 0);
  lcd.print("STATIE DE LIPIT");
  myPID.SetMode(AUTOMATIC);
  myPID.SetOutputLimits(0, 25);
  pinMode(relay, OUTPUT);
  pinMode(potentiometer, INPUT);
  pinMode(zerocrossing, INPUT_PULLUP);
  pinMode(triac, OUTPUT);
  delay(1200);
  lcd.clear();
  digitalWrite(triac, LOW);
  digitalWrite(relay, HIGH);
  pidOut = 0;
  attachInterrupt(digitalPinToInterrupt(2), zero_crosss_int, RISING);
}

void loop() {  //moved the PID computations outside the ISR
  pottemperature = analogRead(potentiometer);
  pottemperature = map(pottemperature, 0, 1023, 150, 400); //pottemperature is volatile
  Setpoint = pottemperature;
  realTemperature = thermocouple.readCelsius();
  Input = int(0.779828 * realTemperature - 10.3427); // make temperature an integer  //temperature is volatile
  double gap = abs(Setpoint - Input); //distance away from setpoint
  if (gap < 10)
  { //we're close to setpoint, use conservative tuning parameters
    myPID.SetTunings(consKp, consKi, consKd);
  }
  else
  {
    //we're far from setpoint, use aggressive tuning parameters
    myPID.SetTunings(aggKp, aggKi, aggKd);
  }
  myPID.Compute();
  noInterrupts();  
  pidOut = int(Output);  //pidOut is volatile
  interrupts();
  if (!tempError) {  
    updateDisplay();
  } else 
  {
    if (!shownError) { 
      displayErrors();
      shownError = true; 
    }
  }
  delay(250);
}

void zero_crosss_int() {
  counter++;
  if (counter > duty) { 
    digitalWrite(triac, LOW);
  }
  if (counter >= 25) {
    counter = 0;
    if (tempError || isnan(realTemperature) || Setpoint >= 432) { 
      tempError = true; 
    }
    else { //reading valid
      duty = constrain(pidOut, 0, 25); 
      if (duty > 0) {
        digitalWrite(triac, HIGH);
      } else {
        digitalWrite(triac, LOW);
      }
    }
  } 
}

void updateDisplay() {
  pottemperature = analogRead(potentiometer);
  Setpoint = map(pottemperature, 0, 1023, 150, 400);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.write((byte)0);
  lcd.setCursor(2, 0);
  lcd.print((int)Setpoint);
  lcd.setCursor(6, 0);
  lcd.print((char)223); //degree sign
  lcd.setCursor(7, 0);
  lcd.print("C");
  lcd.setCursor(0, 1);
  lcd.write((byte)1);
  if (Input <= 45) {
    lcd.setCursor(2, 1);
    lcd.print("Lo");
  } else {
    lcd.setCursor(2, 1);
    lcd.print((int)Input);
  }
  lcd.setCursor(6, 1);
  lcd.print("[");
  lcd.setCursor(7, 1);
  lcd.print((int)realTemperature);
  lcd.setCursor(10, 1);
  lcd.print("]");
  lcd.setCursor(12, 1);
  lcd.print((char)223);
  lcd.setCursor(13, 1);
  lcd.print("C");
}

void displayErrors() {
  digitalWrite(relay, LOW); 
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.write((byte)0);
  lcd.setCursor(1, 0);
  lcd.write((byte)0);
  lcd.setCursor(5, 0);
  lcd.print("ERROR!");
  lcd.setCursor(14, 0);
  lcd.write((byte)0);
  lcd.setCursor(15, 0);
  lcd.write((byte)0);
}

I don't know for sure if the code is correct, I just checked it and it seems to work, but I need your advice.

What's your problem? What doesn't work as expected?

Why is gap double, why pidOut volatile?

I think the weather is poor for the time of year :slight_smile: