Hello, I have built the attached schematic and I have the attached code.
I have 2 questions:
1. How to correctly write the loop() function ?
2. And how to correctly write the zero() function ?
I have 2 questions:
1. How to correctly write the loop() function ?
2. And how to correctly write the zero() function ?
C:
#include <LiquidCrystal.h>
#include <SPI.h>
#include <Wire.h>
#include <max6675.h>
#define thermoDO 12
#define thermoCS 10
#define thermoCLK 13
#define potentiometer A0
#define zerocrossing 2
#define triac 7
#define relay A1
volatile float temperature, realTemperature; // I have declared those 2 variables as VOLATILE, because of using them inside and outside ISR
int pottemperature;
int counter;
int duty = 0; // variable for duty cycle
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 sensed_output, control_signal;
double setPoint;
double Kp; //proportional gain
double Ki; //integral gain
double Kd; //derivative gain
int T = 100; //sample time in milliseconds (ms)
unsigned long last_time = 0;
double total_error, last_error;
int max_control = 0;
int min_control = 240;
LiquidCrystal lcd(3, 4, 5, 6, 8, 9);
void setup() {
lcd.createChar(0, thermometer);
lcd.createChar(1, arrow);
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print("STATIE DE LIPIT");
delay(1200);
lcd.clear();
pinMode(relay, OUTPUT);
pinMode(potentiometer, INPUT);
pinMode(zerocrossing, INPUT_PULLUP);
pinMode(triac, OUTPUT);
digitalWrite(triac, LOW);
digitalWrite(relay, HIGH);
realTemperature = thermocouple.readCelsius();
temperature = 0.779828 * realTemperature - 10.3427;
//updateDisplay();
attachInterrupt(digitalPinToInterrupt(2), zero_crosss_int, RISING);
}
void loop() { //moved the PID computations outside the ISR
unsigned long current_time = millis(); //returns the number of milliseconds passed since the Arduino started running the program
int delta_time = current_time - last_time; //delta time interval
pottemperature = analogRead(potentiometer);
pottemperature = map(pottemperature, 0, 1023, 150, 400);
setPoint = pottemperature;
realTemperature = thermocouple.readCelsius();
temperature = int(0.779828 * realTemperature - 10.3427); // make temperature an integer
sensed_output = temperature;
updateDisplay();
if (isnan(realTemperature) || temperature >= 432) {
while (true) {
displayErrors();
}
}
if (delta_time >= T) {
double error = setPoint - sensed_output;
if (error <= 10) {
Kp = 4, Ki = 0.2, Kd = 1;
}
if (error > 10) {
Kp = 1, Ki = 0.05, Kd = 0.25;
}
total_error += error; //accumalates the error - integral term
if (total_error >= max_control) total_error = max_control;
else if (total_error <= min_control) total_error = min_control;
double delta_error = error - last_error; //difference of error for derivative term
control_signal = Kp * error + (Ki * T) * total_error + (Kd / T) * delta_error; //PID control compute
if (control_signal >= max_control) control_signal = max_control;
else if (control_signal <= min_control) control_signal = min_control;
last_error = error;
}
noInterrupts();
pidOut = int(control_signal);
interrupts();
last_time = current_time;
delay(250);
}
void zero_crosss_int()
{
int powertime = (39 * (256 - pidOut));
delayMicroseconds(powertime);
digitalWrite(triac, HIGH);
delayMicroseconds(10);
digitalWrite(triac, LOW);
}
void updateDisplay() {
pottemperature = analogRead(potentiometer);
pottemperature = map(pottemperature, 0, 1023, 150, 400);
lcd.clear();
lcd.setCursor(0, 0);
lcd.write((byte)0);
lcd.setCursor(2, 0);
lcd.print((int)pottemperature);
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 (temperature <= 45) {
lcd.setCursor(2, 1);
lcd.print("Lo");
} else {
lcd.setCursor(2, 1);
lcd.print((int)temperature);
}
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); // the relay will disconnect the power to the soldering iron heating element
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);
delay(500);
}
Attachments
Last edited: