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