#include <max6675.h>
#include <LiquidCrystal_I2C.h>
// Definición de pines
#define START A2
#define STOP A3
#define KTC_SO 2
#define KTC_CS 3
#define KTC_CLK 4
#define LED_PRO 5
#define BUZZER 6
#define LED_SET 7
#define SSR 8
#define ENCODER_CLK 9
#define ENCODER_DT 10
#define ENCODER_SW 11
byte termo[] = {
0b00100,
0b01110,
0b01110,
0b01010,
0b10001,
0b10001,
0b01110,
0b00000
};
byte reloj[] = {
0b00000,
0b01110,
0b10101,
0b10101,
0b10111,
0b10001,
0b01110,
0b00000
};
unsigned int setpoint_temp = 100; // Valor inicial de temperatura
unsigned int tiempo = 300; // Valor inicial de tiempo en segundos
unsigned long PREV_MILLIS = 0;
unsigned long PREV_MILLIS_TEMPERATURA = 0;
const int FALSE = 0;
const int TRUE = 1;
short FLAG_STOP = 0;
char buffer[16];
LiquidCrystal_I2C lcd(0x27, 16, 2);
MAX6675 ktc(KTC_CLK, KTC_CS, KTC_SO);
int ultimaPosicionClk = HIGH;
int mode = 0; // 0: Ajustar temperatura, 1: Ajustar tiempo
void setup() {
lcd.begin(16, 2);
lcd.init();
lcd.backlight();
pinMode(START, INPUT_PULLUP);
pinMode(STOP, INPUT_PULLUP);
pinMode(BUZZER, OUTPUT);
pinMode(LED_PRO, OUTPUT);
pinMode(SSR, OUTPUT);
pinMode(LED_SET, OUTPUT);
pinMode(ENCODER_CLK, INPUT);
pinMode(ENCODER_DT, INPUT);
pinMode(ENCODER_SW, INPUT_PULLUP);
lcd.createChar(1, termo);
lcd.createChar(2, reloj);
// Predeterminar el tiempo a 5 minutos (300 segundos)
tiempo = 300;
// Espera a que se presione el botón de inicio
while (digitalRead(START) || tiempo == 0) {
check_encoder();
display_temp(setpoint_temp);
display_tiempo();
}
digitalWrite(LED_PRO, HIGH);
digitalWrite(SSR, HIGH);
// Inicialización de las variables de tiempo
PREV_MILLIS_TEMPERATURA = millis() - 500;
PREV_MILLIS = millis();
}
void loop() {
while (FLAG_STOP == FALSE) {
unsigned long CURRENT_MILLIS = millis();
if (CURRENT_MILLIS - PREV_MILLIS_TEMPERATURA >= 500) {
unsigned int temperatura = ktc.readCelsius();
PREV_MILLIS_TEMPERATURA = CURRENT_MILLIS;
display_temp(temperatura);
display_tiempo();
control_actuador(temperatura);
}
if (CURRENT_MILLIS - PREV_MILLIS >= 1000) {
tiempo--;
PREV_MILLIS += 1000;
}
if (!digitalRead(STOP) || (tiempo == 0)) {
FLAG_STOP = TRUE;
}
}
while (FLAG_STOP) {
digitalWrite(SSR, LOW);
digitalWrite(LED_PRO, LOW);
final_proceso();
while (digitalRead(START) || tiempo == 0) {
check_encoder();
display_temp(setpoint_temp);
display_tiempo();
}
digitalWrite(LED_PRO, HIGH);
digitalWrite(SSR, HIGH);
FLAG_STOP = FALSE;
}
}
void check_encoder() {
int posicionActualClk = digitalRead(ENCODER_CLK);
unsigned int dtEncoder = digitalRead(ENCODER_DT);
if (posicionActualClk != ultimaPosicionClk) {
if (posicionActualClk == LOW && dtEncoder == HIGH) {
if (mode == 0) { // Ajustar temperatura
setpoint_temp++;
} else { // Ajustar tiempo
tiempo++;
}
}
if (posicionActualClk == LOW && dtEncoder == LOW) {
if (mode == 0) { // Ajustar temperatura
setpoint_temp--;
} else { // Ajustar tiempo
tiempo--;
}
}
}
ultimaPosicionClk = posicionActualClk;
// Detección del botón del encoder
if (digitalRead(ENCODER_SW) == LOW) {
delay(50); // Debounce
if (digitalRead(ENCODER_SW) == LOW) {
mode = !mode; // Alternar entre temperatura y tiempo
while (digitalRead(ENCODER_SW) == LOW); // Espera a que se suelte el botón
}
}
}
void display_temp(int cache_temp) {
lcd.setCursor(2, 0);
lcd.print("SENSOR");
lcd.setCursor(10, 0);
sprintf(buffer, "%u%c ", cache_temp, 0xDF);
lcd.print(buffer);
lcd.setCursor(0, 0);
lcd.write((byte)1);
}
void display_temp_loop(int cache_temp_set, int cache_temp_actual) {
lcd.setCursor(0, 0);
sprintf(buffer, "S:%d%cC ACT:%u%c ", cache_temp_set, 0xDF, cache_temp_actual, 0xDF);
lcd.print(buffer);
}
void display_tiempo() {
unsigned int minuto, segundo;
minuto = tiempo / 60;
segundo = tiempo % 60;
lcd.setCursor(2, 1);
lcd.print("TIEMPO");
lcd.setCursor(0, 1);
lcd.write((byte)2);
lcd.setCursor(10, 1);
sprintf(buffer, "%u:%0.2u", minuto, segundo);
lcd.print(buffer);
}
void final_proceso() {
lcd.clear();
lcd.setCursor(4, 0);
lcd.print("PROCESO");
lcd.setCursor(3, 1);
lcd.print("FINALIZADO");
digitalWrite(LED_PRO, LOW);
digitalWrite(LED_SET, LOW);
digitalWrite(SSR, LOW);
digitalWrite(BUZZER, HIGH);
delay(1000);
digitalWrite(BUZZER, LOW);
delay(1000);
lcd.clear();
}
void control_actuador(unsigned int temperatura) {
if (temperatura >= setpoint_temp) {
digitalWrite(SSR, LOW);
digitalWrite(LED_SET, LOW);
} else {
digitalWrite(SSR, HIGH);
digitalWrite(LED_SET, HIGH);
}
}