Salir y continuar de blucle for

Aquí está mi versión con máquina de estados. Aunque de entrada es más complicado y enrevesado de hacer con una máquina de estados, en cuanto quieres hacer más cosas la máquina de estado te lo simplifica mucho.

#include "max6675.h"
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 20 , 4);
// 0x27 0x3F , 0x20 , 0x38 ,  16 , 2 20 , 4

const byte CANTIDAD_CICLOS  = 2;                        // Cantidad de ciclos intermedios que se quiere
const int MAXIMO_CALENTANDO = 39.0;                     // Temperatura hasta que se ha de calentar en los ciclos intermedios
const int MINIMO_ENFRIANDO  = 36.0;                     // Temperatura hasta que se ha de enfriar en los ciclos intermedios
const int MAXIMO_CALENTANDO_FINAL_A = 40.0;             // Temperatura hasta que se ha de calentar al final (opción A)
const int MAXIMO_CALENTANDO_FINAL_B = 42.0;             // Temperatura hasta que se ha de calentar al final (opción B)
const int MINIMO_ENFRIANDO_FINAL    = 29.0;             // Temperatura hasta que se ha de enfriar para apagar el ventilador
const unsigned long INTERVALO_ENTRE_LECTURAS = 2500UL;  // Milisegundos que han de transcurrir entre cada lectura de la temperatura
const bool FLECHAS = true;                              // Cambia las "animaciones" dependiedo de si se define true o false

// Definición de los pines usados
const byte THERMO_DO  = 6;  // Pines a los que está conectado el sensor de termperatura
const byte THERMO_CS  = 5;
const byte THERMO_CLK = 4;
const byte PIN_SELECTOR_TEMPERATURA = 10;   // Pin de selector de temperatura final (opción A o B)
const byte PIN_RELE_CALENTADOR      = 12;   // Pin al que está conectado el relé del calentador
const byte PIN_RELE_VENTILADOR      = 13;   // Pin al que está conectado el relé del ventilador

// Lo siguiente lo he respetado del código original porque no tengo claro qué es lo que se está haciendo con ello
const byte vccPin     = 3;
const byte gndPin     = 2;
const byte gndPinf    = 8;
const byte vccPinr    = 9;

const byte VALOR_RELE_ACTIVADO = LOW;                   // Valor que ha de tener el pin para que se active el relé
const byte VALOR_RELE_APAGADO  = !VALOR_RELE_ACTIVADO;  // Esta definición no hay que tocarla nunca, se ha de modificar la de VALOR_RELE_ACTIVADO si fuera necesario

MAX6675 thermocouple(THERMO_CLK, THERMO_CS, THERMO_DO);
float temperatura = 20;                         // Almacena el valor de la temperatura
unsigned long instanteAnterior = 0;             // Para controlar las pausas en la máquina de estados
unsigned long instanteAnteriorTemperatura = 0;  // Para controlar el tiempo transcurrido desde la última lectura de temperatura
unsigned long instanteAnteriorCaracter = 0;     // Para controlar el tiempo de la animación de los caractéres
byte ciclo = 0;                                 // Lleva la cuenta del ciclo en que se encuentra
byte pasoCaracter = 0;                          // Para controlar en que paso está de la animación de los caractéres (todos tienen cuato pasos)
int temperaturaCalentamientoFinal = 0;          // Almacena el valor de la temperatura del calentamiento final que vale según la posición del delector de temperatura
int temperaturaCalentamientoFinalAnterior = 0;  // Tan solo es para ver si ha cambiado el valor de temperaturaCalentamientoFinal. Si es así, actualiza su visualización en el LCD

// Definición del enumerado y de la variable que guarda en qué estado se encuentra la máquina de estado
enum estado_t {
  ESTADO_INICIAL,
  ESTADO_PRESENTACION,
  ESTADO_CALENTANDO,
  ESTADO_ENFRIANDO,
  ESTADO_CALENTANDO_FINAL,
  ESTADO_ENFRIANDO_FINAL,
  ESTADO_FINAL
} estado = ESTADO_INICIAL;

// Definiciones de los caractéres para la animación
byte cararterSubir[4][8] = {
  {
    B00100,
    B01110,
    B11011,
    B10001,
    B00100,
    B01110,
    B11011,
    B10001
  }
  , {
    B01110,
    B11011,
    B10001,
    B00100,
    B01110,
    B11011,
    B10001,
    B00100
  }
  , {
    B11011,
    B10001,
    B00100,
    B01110,
    B11011,
    B10001,
    B00100,
    B01110
  }
  , {
    B10001,
    B00100,
    B01110,
    B11011,
    B10001,
    B00100,
    B01110,
    B11011
  }
};

byte cararterBajar[4][8] = {
  {
    B10001,
    B11011,
    B01110,
    B00100,
    B10001,
    B11011,
    B01110,
    B00100
  }
  , {
    B00100,
    B10001,
    B11011,
    B01110,
    B00100,
    B10001,
    B11011,
    B01110
  }
  , {
    B01110,
    B00100,
    B10001,
    B11011,
    B01110,
    B00100,
    B10001,
    B11011
  }
  , {
    B11011,
    B01110,
    B00100,
    B10001,
    B11011,
    B01110,
    B00100,
    B10001
  }
};

byte cararterCalentar[4][8] = {
  {
    B00001,
    B01001,
    B10010,
    B10010,
    B01001,
    B01001,
    B10100,
    B01110
  }
  , {
    B01000,
    B10010,
    B10010,
    B01001,
    B01001,
    B10010,
    B00110,
    B01110
  }
  , {
    B00010,
    B10010,
    B01001,
    B01001,
    B10010,
    B10010,
    B01100,
    B01110
  }
  , {
    B10000,
    B01001,
    B01001,
    B10010,
    B10010,
    B01001,
    B00101,
    B01110
  }
};

byte cararterEnfriar[4][8] = {
  {
    B00000,
    B00110,
    B11001,
    B00000,
    B10011,
    B01100,
    B00100,
    B01110
  }
  , {
    B00000,
    B10011,
    B01100,
    B00000,
    B11001,
    B00110,
    B00100,
    B01110
  }
  , {
    B00000,
    B11001,
    B00110,
    B00000,
    B01100,
    B10011,
    B00100,
    B01110
  }
  , {
    B00000,
    B01100,
    B10011,
    B00000,
    B00110,
    B11001,
    B00100,
    B01110
  }
};

void setup() {
  Serial.begin(9600);
  lcd.init();
  lcd.backlight();
  pinMode(PIN_RELE_CALENTADOR, OUTPUT);
  digitalWrite(PIN_RELE_CALENTADOR, VALOR_RELE_APAGADO);
  pinMode(PIN_RELE_VENTILADOR, OUTPUT);
  digitalWrite(PIN_RELE_VENTILADOR, VALOR_RELE_APAGADO);
  pinMode(PIN_SELECTOR_TEMPERATURA, INPUT);


  // Lo siguiente lo he respetado del código original porque no tengo claro qué es lo que se está haciendo con ello
  pinMode(vccPin, OUTPUT);
  digitalWrite(vccPin, HIGH);

  // Lo siguiente lo he respetado del código original porque no tengo claro qué es lo que se está haciendo con ello
  pinMode(gndPin, OUTPUT);
  digitalWrite(gndPin, LOW);

  // Lo siguiente lo he respetado del código original porque no tengo claro qué es lo que se está haciendo con ello
  pinMode(vccPinr, OUTPUT);
  digitalWrite(vccPinr, HIGH);

  // Lo siguiente lo he respetado del código original porque no tengo claro qué es lo que se está haciendo con ello
  pinMode(gndPinf, OUTPUT);
  digitalWrite(gndPinf, LOW);
}

void loop() {
  unsigned long instanteActual = millis();
  bool refrescarLCD = false;
  bool refrescarTemperaturaFinal = false;
  if ((instanteActual - instanteAnteriorCaracter) >= 250UL) {
    instanteAnteriorCaracter = instanteActual;
    pasoCaracter = (pasoCaracter + 1) % 4;
    if (FLECHAS) {
      lcd.createChar(0, cararterSubir[pasoCaracter]);
      lcd.createChar(1, cararterBajar[pasoCaracter]);
    }
    else {
      lcd.createChar(0, cararterCalentar[pasoCaracter]);
      lcd.createChar(1, cararterEnfriar[pasoCaracter]);
    }
  }
  if ((instanteActual - instanteAnteriorTemperatura) >= INTERVALO_ENTRE_LECTURAS) {
    instanteAnteriorTemperatura = instanteActual;
    temperatura = thermocouple.readCelsius();
    refrescarLCD = true;
  }
  temperaturaCalentamientoFinal = (digitalRead(PIN_SELECTOR_TEMPERATURA) ? MAXIMO_CALENTANDO_FINAL_A : MAXIMO_CALENTANDO_FINAL_B);
  if (temperaturaCalentamientoFinal != temperaturaCalentamientoFinalAnterior) {
    temperaturaCalentamientoFinalAnterior = temperaturaCalentamientoFinal;
    refrescarLCD = true;
    refrescarTemperaturaFinal = true;
  }
  switch (estado) {
    case ESTADO_INICIAL :
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(F("D. Marmo Servicios")); // Mensaje a desplegar
      lcd.setCursor(0, 2);
      lcd.print(F("    Secadora Do 6 ")); // Mensaje 2 a desplegar
      refrescarLCD = false;
      instanteAnterior = instanteActual;
      estado = ESTADO_PRESENTACION;
      break;
    case ESTADO_PRESENTACION :
      refrescarLCD = false;
      if ((instanteActual - instanteAnterior) >= 3000UL) {
        digitalWrite(PIN_RELE_VENTILADOR, VALOR_RELE_ACTIVADO);
        digitalWrite(PIN_RELE_CALENTADOR, VALOR_RELE_ACTIVADO);
        lcd.clear();
        if (CANTIDAD_CICLOS == 0) {
          estado = ESTADO_CALENTANDO_FINAL;
          lcd.setCursor(0, 3);
        }
        else {
          ciclo = 1;
          estado = ESTADO_CALENTANDO;
          lcd.setCursor(1, 2);
          lcd.print(MAXIMO_CALENTANDO);
          lcd.write(223);
          lcd.print('/');
          lcd.print(MINIMO_ENFRIANDO);
          lcd.write(223);
          lcd.setCursor(14, 1);
          lcd.print(MAXIMO_CALENTANDO);
          lcd.write(223);
          lcd.setCursor(0, 2);
        }
        lcd.write(0);
        lcd.setCursor(1, 3);
        lcd.print(temperaturaCalentamientoFinal);
        lcd.write(223);
        lcd.print('/');
        lcd.print(MINIMO_ENFRIANDO_FINAL);
        lcd.write(223);
        refrescarLCD = true;
      }
      break;
    case ESTADO_CALENTANDO :
      if (temperatura >= MAXIMO_CALENTANDO) {
        digitalWrite(PIN_RELE_CALENTADOR, VALOR_RELE_APAGADO);
        estado = ESTADO_ENFRIANDO;
        lcd.setCursor(0, 2);
        lcd.write(' ');
        lcd.setCursor(8, 2);
        lcd.write(1);
        lcd.setCursor(14, 1);
        lcd.print(MINIMO_ENFRIANDO);
        lcd.write(223);
      }
      break;
    case ESTADO_ENFRIANDO :
      if (temperatura <= MINIMO_ENFRIANDO) {
        digitalWrite(PIN_RELE_CALENTADOR, VALOR_RELE_ACTIVADO);
        if (ciclo >= CANTIDAD_CICLOS) {
          estado = ESTADO_CALENTANDO_FINAL;
          lcd.setCursor(2, 1);
          lcd.print(F("   "));
          lcd.setCursor(0, 3);
        }
        else {
          ciclo++;
          estado = ESTADO_CALENTANDO;
          lcd.setCursor(14, 1);
          lcd.print(MAXIMO_CALENTANDO);
          lcd.write(223);
          lcd.setCursor(0, 2);
        }
        lcd.write(0);
        lcd.setCursor(8, 2);
        lcd.write(' ');
      }
      break;
    case ESTADO_CALENTANDO_FINAL :
      if (temperatura >= temperaturaCalentamientoFinal) {
        digitalWrite(PIN_RELE_CALENTADOR, VALOR_RELE_APAGADO);
        estado = ESTADO_ENFRIANDO_FINAL;
        lcd.setCursor(0, 3);
        lcd.write(' ');
        lcd.setCursor(8, 3);
        lcd.write(1);
        lcd.setCursor(14, 1);
        lcd.print(MINIMO_ENFRIANDO_FINAL);
        lcd.write(223);
      }
      break;
    case ESTADO_ENFRIANDO_FINAL :
      if (temperatura <= MINIMO_ENFRIANDO_FINAL) {
        digitalWrite(PIN_RELE_CALENTADOR, VALOR_RELE_APAGADO);
        digitalWrite(PIN_RELE_VENTILADOR, VALOR_RELE_APAGADO);
        estado = ESTADO_FINAL;
        lcd.clear();
        lcd.setCursor(3, 2);
        lcd.print(F("FIN DE PROCESO"));
        refrescarLCD = true;
        refrescarTemperaturaFinal = false;
      }
    case ESTADO_FINAL :
      // No hace nada
      break;
  }

  if (refrescarLCD) {
    bool mostrarPasos = false;
    char subeBaja = ' ';
    lcd.setCursor(1, 0);
    switch (estado) {
      case ESTADO_INICIAL :
      case ESTADO_PRESENTACION :
      case ESTADO_FINAL :
        refrescarTemperaturaFinal = false;
        break;
      case ESTADO_CALENTANDO :
        lcd.print(F("CALENTANDO"));
        subeBaja = 0;
        mostrarPasos = true;
        break;
      case ESTADO_ENFRIANDO :
        lcd.print(F("ENFRIANDO "));
        mostrarPasos = true;
        subeBaja = 1;
        break;
      case ESTADO_CALENTANDO_FINAL :
        lcd.print(F("CALENTANDO"));
        subeBaja = 0;
        lcd.setCursor(14, 1);
        lcd.print(temperaturaCalentamientoFinal);
        lcd.write(223);
        break;
      case ESTADO_ENFRIANDO_FINAL :
        lcd.print(F("ENFRIANDO "));
        subeBaja = 1;
        break;
    }
    if (refrescarTemperaturaFinal) {
        lcd.setCursor(1, 3);
        lcd.print(temperaturaCalentamientoFinal);
    }
    if (mostrarPasos) {
      lcd.setCursor(3 - (ciclo / 10), 1);
      lcd.print(ciclo);
      lcd.print('/');
      lcd.print(CANTIDAD_CICLOS);
      lcd.print('x');
    }
    // Mostrar temperatura
    lcd.setCursor(13, 0);
    if ((temperatura < 200) && (temperatura > -99)) {
      if ((temperatura < 100) && (temperatura > -10)) {
        lcd.write(' ');
      }
      if ((temperatura < 10) && (temperatura >= 0)) {
        lcd.write(' ');
      }
      lcd.print(temperatura);
    }
    else {
      lcd.print(F(" --.--"));
    }
    lcd.write(223);
    lcd.setCursor(17, 1);
    lcd.write(subeBaja);
  }
}

La definición y uso de las constantes vccPin, gndPin, gndPinf y vccPinr las «he respetado» porque no tengo claro qué es lo que hacer con ellas. Todo lo demás creo que poco se parece al código que tenías. Pero eso es normal cuando pasas a máquinas de estado

En todo mi código no hay ni un solo for ni while. No quiero decir con esto que no se usen cuando se emplean máquinas de estado. Sí se pueden usar, pero para «cosas puntuales».

El programa no tiene ningún Serial.print() ya que muestra en todo momento en el LCD lo que está haciendo. Muestra algo por el estilo a esto:

 CALENTANDO   29.72º
   1/2x       39º*
*39º/36º
 42º/29º

Indica si se está calentando o enfriando (CALENTANDO en el ejemplo). Arriba a la derecha la temperatura tomada por el sensor (29.72º). Justo debajo la temperatura que se quiere alcanzar (39º). El asterisco de al lado no es realmente un asterisco, es un carácter animado según se esté calentando o enfriando, pero eso sólo se puede ver en el LCD. El 1/2 indica que está en ciclo uno de dos. El 39º/36º son las temperaturas a la que se ha de calentar y enfriar en cada ciclo. El asterisco al lado del 39º es el carácter animado que indica que es esa la temperatura que se está tratando de alcanzar actualmente. Y por último el 42º/29º son las temperaturas a las que se ha de dar el último calentón y a la que se ha de dejar enfriar para apagar el ventilador. Pero todo esto se ve mejor en el LCD con el programa funcionando.

Si la lectura de la temperatura registrada por el sensor es superior o igual a los 200º, inferior o igual a -99º o da un NaN (no es un número) por algún error, se muestra --.--º como lectura de la temperatura.

En principio lo que has de ajustar según tus necesidades son las constantes:

const byte CANTIDAD_CICLOS  = 2;                        // Cantidad de ciclos intermedios que se quiere
const int MAXIMO_CALENTANDO = 39.0;                     // Temperatura hasta que se ha de calentar en los ciclos intermedios
const int MINIMO_ENFRIANDO  = 36.0;                     // Temperatura hasta que se ha de enfriar en los ciclos intermedios
const int MAXIMO_CALENTANDO_FINAL_A = 40.0;             // Temperatura hasta que se ha de calentar al final (opción A)
const int MAXIMO_CALENTANDO_FINAL_B = 42.0;             // Temperatura hasta que se ha de calentar al final (opción B)
const int MINIMO_ENFRIANDO_FINAL    = 29.0;             // Temperatura hasta que se ha de enfriar para apagar el ventilador
const unsigned long INTERVALO_ENTRE_LECTURAS = 2500UL;  // Milisegundos que han de transcurrir entre cada lectura de la temperatura
const bool FLECHAS = true;                              // Cambia las "animaciones" dependiedo de si se define true o false
  • CANTIDAD_CICLOS determina el número de veces que se han de alcanzar la temperatura máxima y mínima de los ciclos antes de pasar a alcanzar la temperatura máxima final. Puede ser cualquier valor entre cero y 99. Si es cero, no aparecerá en el LCD ni el número de ciclos ni los valores de las temperaturas máxima y mínima de los ciclos. Tan sólo aparecerá la temperatura máxima final y la temperatura mínima a la que se ha de apagar.
  • MAXIMO_CALENTANDO es la temperatura máxima que se ha de alcanzar en los ciclos al calentar.
  • MINIMO_ENFRIANDO es la temperatura mínima que se ha de alcanzar en los ciclos en el enfriado.
  • MAXIMO_CALENTANDO_FINAL_A y MAXIMO_CALENTANDO_FINAL_B son las dos temperaturas que se pueden seleccionar con el conmutador a la que ha de llegar en el calentamiento final.
  • MINIMO_ENFRIANDO_FINAL es la temperatura a la que se ha de llegar para finalizar el proceso y apagar el ventilador en el enfriamiento final.
  • INTERVALO_ENTRE_LECTURAS indica cada cuántos milisegundos se ha de tomar una muestra de temperatura. Es aconsejable ponerle el sufijo UL a ese número, para indicarle al compilador que es unsigned long porque por defecto trata los literales numéricos como int y nos podríamos llevar una sorpresa si la cantidad de milisegundos fuera mayor a 65535. Supongo que no será este el caso, pero es bueno acostumbrarse a ponerlo.
  • FLECHAS los caracteres animados que indican si se está calentando o enfriando serán otros dependiendo de si se indica un true o un false en la definición de esta constante. Prueba a cambiar el valor y ya me dirás si finalmente has dejado las flechas o has preferido «los otros». Siempre podrás cambiar el código y definir otras animaciones. Lo que está puesto a fuego que son 4 los «pasos» de cada animación.

Lo creas o no, esta es la versión «rápida» y sin muchas florituras (aunque algunas hay). Creo que la versión «buena» debería de permitir que se pudieran configurar las temperaturas desde el mismo Arduino, sin tener que estar modificando, compilando y cargando el programa al Arduino cada vez que vas a cambiar las temperaturas. Yo quitaría el conmutador que tienes para seleccionar entre las dos temperaturas máximas finales y le pondría tres pulsadores. Uno para incrementar el valor de cada temperatura, otro para decrementar y un tercero para «avanzar» a la siguiente temperatura. No hace falta más, ni tan siquiera para «volver» a la anterior. Bastaría con pulsar varias veces hasta «pasar» por todas y «volver» a la primera cíclicamente. Pero si se quiere se pueden poner más pulsadores con más funcionalidades. Quien dice que son para configurar las temperaturas, también sirven para cambiar el número de ciclos a realizar. Así como para indicar que empiece el proceso una vez configurado o que lo interrumpa por si se quiere empezar de nuevo o cambiar algún parámetro. Y ya, para hacerlo más cómodo aún, que pueda guardar en la EEPROM al menos los últimos valores configurados para tenerlos ya al encender el Arduino. Aunque yo no me quedaría ahí, sino que también se puedan guardar varias configuraciones distintas en la EEPROM.

Una cosa que el programa no tiene en cuenta es qué hacer si hay un error de lectura de la temperatura. Esta versión tan sólo muestra --.--º en la esquina superior derecha. Creo que tal vez debería de al menos apagar el calentador en el caso de que estuviera calentando. El ventilador no creo que haga falta pararlo. Y en el caso de volver a recuperar el valor de la temperatura, entonces continuar con lo que estaba haciendo y encender el calentador sólo si tiene que calentar.

Otra posible mejora creo que sería el añadir otro sensor para obtener la temperatura ambiente. Ya que creo recordar que dijiste que la temperatura a la que ha de finalizar todo el proceso ha de ser unos ocho grados por encima de la temperatura ambiente. En tal caso no haría falta configurarla para nada. Tal vez, en su lugar, poder configurar si son ocho u otro valor los grados por encima de la temperatura ambiente a la que se ha de terminar el proceso. Eso sí, el sensor ha de estar en un lugar adecuado para tomar lo que se ve a considerar «temperatura ambiente».

Pido perdón por tan extensa respuesta… Y aún así creo que me dejo cosas sin comentar. Además de por no haber comentado mucho el código. Pero no puedo dedicarle tanto tiempo como quisiera y tengo ganas de saber si te va bien.

Cualquier duda, pregunta, sugerencia, queja, crítica, idea, consejo, desvarío, consideración, alternativa, lamento o lo que sea: será bienvenida :lying_face:.

Hola ignoranteAbsoluto, esta precioso el código, no logro entender lo del todo, funciona muy bien, muy clara la información desplegada en el display. y si lo de un apagado del calentamiento en caso de emergencia, seria buena la idea lo de los botones, seria muy cómoda la programación, lo mas interesante es lo de dos sondas calentar y ambiente, a un que la mejor parte del código, es que permitirá aprender a crear programas con maquinas de estado, y si tengo un sin numero de dudas preguntas, este fin de semana le are algunos cambios mecánicos y hardware a la deshidratadora y subiré el código para hacer pruebas en tiempo real.
De momento solo me queda, felicitar al foro Arduino por tener miembros como usted que hacen de Arduino toda una experiencia de creatividad, y si es muy fácil cambiar los parámetros de temperatura y tiempos de lectura.
El lunes le comparto mis inquietudes.
Saludos

Hola @silvia96.

He reorganizado el código porque estaba demasiado mezclado el control «principal» con el control de lo que se mostraba en el LCD. He añadido una máquina de estados para controlar la visualización del LCD. Simplemente he añadido la variable estadoLCD y prácticamente todo el código que imprime en el LCD lo he metido en el switch que trabaja con esa variable. En el estado ESTADO_LCD_TRABAJANDO nos valemos del valor del estado de la «máquina principal» (la variable estado) para saber qué se ha de mostrar. En la versión anterior, la máquina de estados principal se encargaba de mostrar u ocultar algunas cosas directamente imprimiendo en el LCD, pero ahora ya no.

He añadido un par de estados más para dar soporte a un posible fallo del sensor de temperatura. Considero un fallo si la temperatura obtenida no está entre los -99º y 200º. En el caso de fallo se apagan tanto el ventilador como el calentador si estuviera encendido. Mostrando «SENSOR MAL» parpadeando. Así como --.--º en el indicador de temperatura. Una vez se vuelva a obtener «valores válidos», se continúa con lo que estaba haciendo. Encendiendo el ventilador y el calentador si procede.

Le he añadido bastantes comentarios, para hacer más comprensible el código. Pero aún así, entiendo que resulte enrevesado si no se tiene costumbre.

He cambiado el nombre de algunas constantes, tratando de hacer un poco más legible el código.

Una cosa a tener en cuenta es cómo funciona los case de un switch cuando hay o no hay break. Dependiendo del valor que tenga la variable del switch la ejecución saltará al case correspondiente hasta que se ejecute un break diréctamente o dentro de un if. Si se llega al siguiente case sin haberse ejecutado ningún break, se continúa como si no hubiese case. Si no se tiene claro, recomiendo mirarlo en internet, pero hay que asegurarse de que es el switch del C o C++. No sirve el de otros lenguajes. Porque el switch funciona de manera muy diferente en diferentes lenguajes de programación.

Un detalle que no mencioné la vez anterior: yo no dispongo de ese sensor de temperatura, así que me he tenido que hacer un apaño para las pruebas. Por lo que no garantizo el funcionamiento al 100%.

Recomiendo “descartar” el código que publiqué anteriormente y mirar sólo este nuevo código:

#include "max6675.h"
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 20 , 4);
// 0x27 0x3F , 0x20 , 0x38 ,  16 , 2 20 , 4

const byte CANTIDAD_CICLOS  = 2;                        // Cantidad de ciclos intermedios que se quiere
const int MAXIMO_CALENTANDO = 39.0;                     // Temperatura hasta que se ha de calentar en los ciclos intermedios
const int MINIMO_ENFRIANDO  = 36.0;                     // Temperatura hasta que se ha de enfriar en los ciclos intermedios
const int MAXIMO_CALENTANDO_FINAL_A = 40.0;             // Temperatura hasta que se ha de calentar al final (opción A)
const int MAXIMO_CALENTANDO_FINAL_B = 42.0;             // Temperatura hasta que se ha de calentar al final (opción B)
const int MINIMO_ENFRIANDO_FINAL    = 29.0;             // Temperatura hasta que se ha de enfriar para apagar el ventilador
const unsigned long INTERVALO_ENTRE_LECTURAS = 2500UL;  // Milisegundos que han de transcurrir entre cada lectura de la temperatura
const bool FLECHAS = true;                              // Cambia las "animaciones" dependiedo de si se define true o false

// Definición de los pines usados
const byte THERMO_DO  = 6;  // Pines a los que está conectado el sensor de termperatura
const byte THERMO_CS  = 5;
const byte THERMO_CLK = 4;
const byte PIN_SELECTOR_TEMPERATURA = 10;   // Pin de selector de temperatura final (opción A o B)
const byte PIN_RELE_CALENTADOR      = 12;   // Pin al que está conectado el relé del calentador
const byte PIN_RELE_VENTILADOR      = 13;   // Pin al que está conectado el relé del ventilador

const byte VALOR_RELE_ENCENDIDO = LOW;                   // Valor que ha de tener el pin para que se active el relé
const byte VALOR_RELE_APAGADO   = !VALOR_RELE_ENCENDIDO; // Esta definición no hay que tocarla nunca, se ha de modificar la de VALOR_RELE_ENCENDIDO si fuera necesario

const char CARACTER_CALENTAR = 0; // Carácter que se usa para la animación que indica que se está calentando
const char CARACTER_ENFRIAR = 1;  // Carácter que se usa para la animación que indica que se está enfriando

// Lo siguiente lo he respetado del código original porque no tengo claro qué es lo que se está haciendo con ello
const byte vccPin     = 3;
const byte gndPin     = 2;
const byte gndPinf    = 8;
const byte vccPinr    = 9;

MAX6675 thermocouple(THERMO_CLK, THERMO_CS, THERMO_DO);
float temperatura = 0;                          // Almacena el valor de la temperatura
bool temperaturaErronea = false;                // Se pone a true si se detecta una temperatura anómala
unsigned long instanteAnterior = 0;             // Para controlar las pausas en la máquina de estados
unsigned long instanteAnteriorTemperatura = 0;  // Para controlar el tiempo transcurrido desde la última lectura de temperatura
unsigned long instanteAnteriorCaracter = 0;     // Para controlar el tiempo de la animación de los caractéres
byte ciclo = 0;                                 // Lleva la cuenta del ciclo en que se encuentra
byte pasoCaracter = 0;                          // Para controlar en que paso está de la animación de los caractéres (todos tienen cuato pasos)
int temperaturaCalentamientoFinal = 0;          // Almacena el valor de la temperatura del calentamiento final que vale según la posición del delector de temperatura
int temperaturaCalentamientoFinalAnterior = 0;  // Tan solo es para ver si ha cambiado el valor de temperaturaCalentamientoFinal. Si es así, actualiza su visualización en el LCD

// Definición del enumerado y de la variable que guarda en qué estado se encuentra la máquina de estados "principal"
enum estado_t {
  ESTADO_INICIAL,                 // Cuando arranca el Arduino. Guarda el instante actual para saber cuándo ha transcurrido el tiempo de presentación y pasa al estado ESTADO_PRESENTACION
  ESTADO_PRESENTACION,            // Espera que transcurra el tiempo de presentación para luego pasar a calentar
  ESTADO_CALENTANDO_CICLO,        // Está calentando durante uno de los ciclos intermedios
  ESTADO_ENFRIANDO_CICLO,         // Está enfriando durante uno de los ciclos intermedios
  ESTADO_CALENTANDO_FINAL,        // Está en el calentantamiento del final
  ESTADO_ENFRIANDO_FINAL,         // Está en el enfriado final
  ESTADO_ERROR_TEMPERATURA,       // Se ha detectado un error en el sensor de temperatura
  ESTADO_PAUSA_ERROR_TEMPERATURA, // Espera a que se quite el error del sensor de temperatura
  ESTADO_FINAL                    // Ha finalizado todo el proceso
};
estado_t estado = ESTADO_INICIAL;         // Variable en la que se guarda el estado de la máquina de estado principal
estado_t estadoGuardado = ESTADO_INICIAL; // Guarda el estado en que estaba cuando se ha producido el error de temperatura, para volver a ese estado cuando se subsane el error

// Definición del enumerado y de la variable que guarda en qué estado se encuentra la máquina de estados que controla la visualizacón del LCD
enum estado_pantalla_t {
  ESTADO_LCD_OCIOSO,              // No ha de hacer nada con el LCD, más que dejarlo tal cual está
  ESTADO_LCD_PRESENTACION,        // Se muestra la presentación y pasa al estado ESTADO_LCD_OCIOSO
  ESTADO_LCD_PREPARAR,            // "Prepara" la pantalla de trabajo, mostrando los valores definidos y que permanecen estáticos
  ESTADO_LCD_TRABAJANDO,          // Muestra y actualiza la información
  ESTADO_LCD_TEMPERATURA,         // Muestra actualizado el valor de la temperatura
  ESTADO_LCD_MUESTRA_FINAL        // Muestra el mensaje de finalización y pasa al estado ESTADO_LCD_TEMPERATURA
} estadoLCD = ESTADO_LCD_OCIOSO;  // Variable en la que se guarda el estado de la máquina de estados del LCD

// Definiciones de los caractéres para la animación
byte cararterSubir[4][8] = {  // Las flechas que suben
  {
    B00100,
    B01110,
    B11011,
    B10001,
    B00100,
    B01110,
    B11011,
    B10001
  }
  , {
    B00100,
    B01010,
    B10001,
    B00100,
    B01110,
    B11011,
    B10001,
    B00000
  }
  , {
    B00000,
      B00000,
      B00100,
      B01110,
      B11011,
      B10001,
      B00000,
      B00000
  }
  , {
    B00000,
      B00100,
      B01110,
      B11011,
      B10001,
      B00100,
      B01010,
      B10001
  }
};

byte cararterBajar[4][8] = {  // Las flechas que bajan
  {
    B10001,
    B11011,
    B01110,
    B00100,
    B10001,
    B11011,
    B01110,
    B00100
  }
  , {
    B00000,
    B10001,
    B11011,
    B01110,
    B00100,
    B10001,
    B01010,
    B00100
  }
  , {
    B00000,
      B00000,
      B10001,
      B11011,
      B01110,
      B00100,
      B00000,
      B00000
  }
  , {
    B10001,
      B01010,
      B00100,
      B10001,
      B11011,
      B01110,
      B00100,
      B00000
  }
};

byte cararterCalentar[4][8] = { // Calentando
  {
    B00001,
    B01001,
    B10010,
    B10010,
    B01001,
    B01001,
    B10100,
    B01110
  }
  , {
    B01000,
    B10010,
    B10010,
    B01001,
    B01001,
    B10010,
    B00110,
    B01110
  }
  , {
    B00010,
      B10010,
      B01001,
      B01001,
      B10010,
      B10010,
      B01100,
      B01110
  }
  , {
    B10000,
      B01001,
      B01001,
      B10010,
      B10010,
      B01001,
      B00101,
      B01110
  }
};

byte cararterEnfriar[4][8] = {  // Enfriando
  {
    B00000,
    B00110,
    B11001,
    B00000,
    B10011,
    B01100,
    B00100,
    B01110
  }
  , {
    B00000,
    B10011,
    B01100,
    B00000,
    B11001,
    B00110,
    B00100,
    B01110
  }
  , {
    B00000,
      B11001,
      B00110,
      B00000,
      B01100,
      B10011,
      B00100,
      B01110
  }
  , {
    B00000,
      B01100,
      B10011,
      B00000,
      B00110,
      B11001,
      B00100,
      B01110
  }
};

void setup() {
  Serial.begin(9600);
  lcd.init();
  lcd.backlight();
  pinMode(PIN_RELE_CALENTADOR, OUTPUT);
  digitalWrite(PIN_RELE_CALENTADOR, VALOR_RELE_APAGADO);  // Inicialmente el calentador está apagado
  pinMode(PIN_RELE_VENTILADOR, OUTPUT);
  digitalWrite(PIN_RELE_VENTILADOR, VALOR_RELE_APAGADO);  // Inicialmente el ventilador está apagado
  pinMode(PIN_SELECTOR_TEMPERATURA, INPUT);
  
  // Lo siguiente lo he respetado del código original porque no tengo claro qué es lo que se está haciendo con ello
  pinMode(vccPin, OUTPUT);
  digitalWrite(vccPin, HIGH);

  // Lo siguiente lo he respetado del código original porque no tengo claro qué es lo que se está haciendo con ello
  pinMode(gndPin, OUTPUT);
  digitalWrite(gndPin, LOW);

  // Lo siguiente lo he respetado del código original porque no tengo claro qué es lo que se está haciendo con ello
  pinMode(vccPinr, OUTPUT);
  digitalWrite(vccPinr, HIGH);

  // Lo siguiente lo he respetado del código original porque no tengo claro qué es lo que se está haciendo con ello
  pinMode(gndPinf, OUTPUT);
  digitalWrite(gndPinf, LOW);
}

void loop() {
  unsigned long instanteActual = millis();                      // Tomamos el instante actual, para controlar los tiempos
  // Animación de los caracteres animados
  if ((instanteActual - instanteAnteriorCaracter) >= 250UL) {   // Cada 250 milisegundos redefinimos los caractéres
    instanteAnteriorCaracter = instanteActual;
    pasoCaracter = (pasoCaracter + 1) % 4;                      // Cada vez que pasa por aquí, pasoCaracter de incrementa en uno volviendo a cero despues de valer 3
    if (FLECHAS) {  // Si se ha definido FLECHAS como true, animará unas flechas ascendentes y descendentes
      lcd.createChar(CARACTER_CALENTAR, cararterSubir[pasoCaracter]);
      lcd.createChar(CARACTER_ENFRIAR, cararterBajar[pasoCaracter]);
    }
    else {          // Si se ha definido FLECHAS como false, animará "otra cosas"
      lcd.createChar(CARACTER_CALENTAR, cararterCalentar[pasoCaracter]);
      lcd.createChar(CARACTER_ENFRIAR, cararterEnfriar[pasoCaracter]);
    }
  }
  // Lectura de la temperatura cada cierto intervalo y control de si se sale del rango "válido" (de -99º a 200º)
  if ((instanteActual - instanteAnteriorTemperatura) >= INTERVALO_ENTRE_LECTURAS) {
    instanteAnteriorTemperatura = instanteActual;
    temperatura = thermocouple.readCelsius();
    temperaturaErronea = !((temperatura < 200) && (temperatura > -99));
  }
  // Control del commutador que selecciona la temperatura máxima final
  temperaturaCalentamientoFinal = (digitalRead(PIN_SELECTOR_TEMPERATURA) ? MAXIMO_CALENTANDO_FINAL_A : MAXIMO_CALENTANDO_FINAL_B);
  if (temperaturaCalentamientoFinal != temperaturaCalentamientoFinalAnterior) {
    temperaturaCalentamientoFinalAnterior = temperaturaCalentamientoFinal;
  }
  // Control de la máquina de estados "principal"
  switch (estado) {
    case ESTADO_INICIAL :
      // Cuando arranca el Arduino. Guarda el instante actual para saber cuándo ha transcurrido el tiempo de presentación y pasa al estado ESTADO_PRESENTACION
      instanteAnterior = instanteActual;    // Nos quedamos con el instante en que empieza a contar el tiempo
      estado = ESTADO_PRESENTACION;         // Pasamos a esperar a que termine el tiempo de la presentación
      estadoLCD = ESTADO_LCD_PRESENTACION;  // Cambia de estado la máquina de estados del LCD para que muestre la presentación
      break;
    case ESTADO_PRESENTACION :
      // Espera que transcurra el tiempo de presentación para luego pasar a calentar
      if ((instanteActual - instanteAnterior) >= 3000UL) {        // Si ha transcurrido el tiempo deseado
        estadoLCD = ESTADO_LCD_PREPARAR;                          // Le dice a la máquina de estados del LCD que muestre los datos "estáticos"
        digitalWrite(PIN_RELE_CALENTADOR, VALOR_RELE_ENCENDIDO);  // Enciende el calentador
        digitalWrite(PIN_RELE_VENTILADOR, VALOR_RELE_ENCENDIDO);  // Enciende el ventilador
        if (CANTIDAD_CICLOS == 0) {
          estado = ESTADO_CALENTANDO_FINAL;   // Si no hay ciclos intermedios, entonces pasa directamente al calentamiento final
        }
        else {                                // Si hay ciclos
          ciclo = 1;                          // Está en el primer ciclo
          estado = ESTADO_CALENTANDO_CICLO;   // Pasa a calentar un ciclo
        }
      }
      break;
    case ESTADO_CALENTANDO_CICLO :
      // Está calentando durante uno de los ciclos intermedios
      if (temperaturaErronea) {             // Si la temperatura es errónea
        estadoGuardado = estado;            // Guarada el estado actual
        estado = ESTADO_ERROR_TEMPERATURA;  // Pasa al estado de error de temperatura
        break;                              // Se sale del switch
      }
      if (temperatura >= MAXIMO_CALENTANDO) {                   // Si se ha alcanzado la temperatura deseada
        digitalWrite(PIN_RELE_CALENTADOR, VALOR_RELE_APAGADO);  // Apaga el calentador
        estado = ESTADO_ENFRIANDO_CICLO;                        // Cambia al estado de enfriamiento del ciclo
      }
      break;
    case ESTADO_ENFRIANDO_CICLO :
      // Está enfriando durante uno de los ciclos intermedios
      if (temperaturaErronea) {             // Si la temperatura es errónea
        estadoGuardado = estado;            // Guarada el estado actual
        estado = ESTADO_ERROR_TEMPERATURA;  // Pasa al estado de error de temperatura
        break;                              // Se sale del switch
      }
      if (temperatura <= MINIMO_ENFRIANDO) {                      // Si se ha alcanzado la temperatura deseada
        digitalWrite(PIN_RELE_CALENTADOR, VALOR_RELE_ENCENDIDO);  // Enciende el calentador
        if (ciclo >= CANTIDAD_CICLOS) {                           // Si estaba en el último ciclo
          estado = ESTADO_CALENTANDO_FINAL;                       // Se pasa a el calentamiento final
        }
        else {                                                    // Si no estaba en el último ciclo
          ciclo++;                                                // Se incrementa el contador de ciclos (el famoso for)
          estado = ESTADO_CALENTANDO_CICLO;                       // Se vuleve a calentar del ciclo
        }
      }
      break;
    case ESTADO_CALENTANDO_FINAL :
      // Está en el calentantamiento del final
      if (temperaturaErronea) {             // Si la temperatura es errónea
        estadoGuardado = estado;            // Guarada el estado actual
        estado = ESTADO_ERROR_TEMPERATURA;  // Pasa al estado de error de temperatura
        break;                              // Se sale del switch
      }
      if (temperatura >= temperaturaCalentamientoFinal) {       // Si se ha alcanzado la temperatura deseada
        digitalWrite(PIN_RELE_CALENTADOR, VALOR_RELE_APAGADO);  // Apaga el calentador
        estado = ESTADO_ENFRIANDO_FINAL;                        // Pasa al enfriamiento final
      }
      break;
    case ESTADO_ENFRIANDO_FINAL :
      // Está en el enfriado final
      if (temperaturaErronea) {             // Si la temperatura es errónea
        estadoGuardado = estado;            // Guarada el estado actual
        estado = ESTADO_ERROR_TEMPERATURA;  // Pasa al estado de error de temperatura
        break;                              // Se sale del switch
      }
      if (temperatura <= MINIMO_ENFRIANDO_FINAL) {              // Si se ha alcanzado la temperatura deseada
        digitalWrite(PIN_RELE_CALENTADOR, VALOR_RELE_APAGADO);  // Apaga el calentador
        digitalWrite(PIN_RELE_VENTILADOR, VALOR_RELE_APAGADO);  // Apaga el ventilador
        estado = ESTADO_FINAL;                                  // Cambia al estado de finalización del proceso
      }
      break;
    case ESTADO_ERROR_TEMPERATURA :
      // Se ha detectado un error en el sensor de temperatura
      // Nos aseguramos de que se apaga el calentador y el ventilador
      digitalWrite(PIN_RELE_CALENTADOR, VALOR_RELE_APAGADO);    // Apaga el calentador
      digitalWrite(PIN_RELE_VENTILADOR, VALOR_RELE_APAGADO);    // Apaga el ventilador
      estado = ESTADO_PAUSA_ERROR_TEMPERATURA;                  // Pasa a esperar a que vuelva a haber una lectura correcta de la temperatura
      break;
    case ESTADO_PAUSA_ERROR_TEMPERATURA :
      // Espera a que se quite el error del sensor de temperatura
      if (!temperaturaErronea) {          // Si la temperatura no es errónea (es correcta)
        estado = estadoGuardado;          // Recupera el estado guardado de la máquina de estado
        switch (estado) {
          case ESTADO_CALENTANDO_CICLO :
          case ESTADO_CALENTANDO_FINAL :
            digitalWrite(PIN_RELE_CALENTADOR, VALOR_RELE_ENCENDIDO);  // Enciende el calentador sólo para los estados ESTADO_CALENTANDO_CICLO y ESTADO_CALENTANDO_FINAL
          case ESTADO_ENFRIANDO_CICLO :
          case ESTADO_ENFRIANDO_FINAL :
            digitalWrite(PIN_RELE_VENTILADOR, VALOR_RELE_ENCENDIDO);  // Enciende el ventilador para los cuatro estados
            break;
          default :
            // No hace enada para todos los demás estados
            break;
        }
      }
      break;
    case ESTADO_FINAL :
      // Ha finalizado todo el proceso
      // No hace nada
      break;
  }

  // Control de lo que se muestra en el LCD ayudado por una máquina de estados propia
  // .. y consultando el estado de la máquina de estado principal
  switch (estadoLCD) {
    case ESTADO_LCD_OCIOSO :
      // No ha de hacer nada con el LCD, más que dejarlo tal cual está
      // No hace nada
      break;
    case ESTADO_LCD_PRESENTACION :
      // Se muestra la presentación y pasa al estado ESTADO_LCD_OCIOSO
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(F("D. Marmo Servicios")); // Mensaje a desplegar
      lcd.setCursor(0, 2);
      lcd.print(F("    Secadora Do 6 ")); // Mensaje 2 a desplegar
      estadoLCD = ESTADO_LCD_OCIOSO;      // Pasa a no hacer nada, hasta que la máquina de estados principal le diga que haga algo
      break;
    case ESTADO_LCD_PREPARAR :
      // "Prepara" la pantalla de trabajo, mostrando los valores definidos y que permanecen estáticos
      lcd.clear();
      if (CANTIDAD_CICLOS != 0) {
        // Si hay ciclos, se muestra las temperaturas de los ciclos
        lcd.setCursor(1, 2);
        lcd.print(MAXIMO_CALENTANDO);
        lcd.write(223);
        lcd.print('/');
        lcd.print(MINIMO_ENFRIANDO);
        lcd.write(223);
      }
      // Se muestran las temperaturas finales
      lcd.setCursor(1, 3);
      lcd.print(temperaturaCalentamientoFinal); // El valor de esta temperatura se ha calculado según el conmutador selector
      lcd.write(223);
      lcd.print('/');
      lcd.print(MINIMO_ENFRIANDO_FINAL);
      lcd.write(223);
      estadoLCD = ESTADO_LCD_TRABAJANDO;        // Pasa al estado de "trabajo", donde muestra el resto de valores
      // No ponemos break ya que queremos que realice las tareas del estado ESTADO_LCD_TRABAJANDO que ha de tratarse a continuación
    case ESTADO_LCD_TRABAJANDO :
      // Muestra y actualiza la información
      { // Creamos un bloque de código dentro de este case porque las siguientes variables sólo van a ser usadas en este case
        bool mostrarPasos = false;    // Tan sólo es para saber si ha de actualizar por qué paso va, ya que está dentro de un ciclo
        int temperaturaDestino = -1;  // Temperatura que se quiere alcanzar. Inicializada a -1 por si no se le asigna valor, que tenga algo que mostrar
        char subeBaja = ' ';          // Carárter animado que indica si se está calentando o enfriando
        char calientaCiclo = ' ';     // Carárter animado que se muestra junto a la temperatura máxima del ciclo
        char enfriaCiclo = ' ';       // Carárter animado que se muestra junto a la temperatura mínima del ciclo
        char calientaFinal = ' ';     // Carárter animado que se muestra junto a la temperatura máxima final
        char enfriaFinal = ' ';       // Carárter animado que se muestra junto a la temperatura mínima final
        lcd.setCursor(1, 0);          // Posiciona el cursor para poner qué es lo que está haciendo
        // Aprovechamos la máquina de estados «principal» para saber qué hemos de mostrar
        switch (estado) {
          case ESTADO_INICIAL :
          case ESTADO_PRESENTACION :
            // No hace nada. Es más, no debería de darse nunca esta condición
            break;
          case ESTADO_CALENTANDO_CICLO :
            lcd.print(F("CALENTANDO"));             // Pone qué está haciendo
            subeBaja = CARACTER_CALENTAR;           // Animación de calentar
            calientaCiclo = CARACTER_CALENTAR;      // Animación de calentar
            mostrarPasos = true;                    // Ha de actualizar la información de por qué paso va
            temperaturaDestino = MAXIMO_CALENTANDO; // Temperatura que se ha de alcanzar
            break;
          case ESTADO_ENFRIANDO_CICLO :
            lcd.print(F("ENFRIANDO "));             // Pone qué está haciendo
            subeBaja = CARACTER_ENFRIAR;            // Animación de enfriar
            enfriaCiclo = CARACTER_ENFRIAR;         // Animación de enfriar
            mostrarPasos = true;                    // Ha de actualizar la información de por qué paso va
            temperaturaDestino = MINIMO_ENFRIANDO;  // Temperatura que se ha de alcanzar
            break;
          case ESTADO_CALENTANDO_FINAL :
            lcd.print(F("CALENTANDO"));                         // Pone qué está haciendo
            subeBaja = CARACTER_CALENTAR;                       // Animación de calentar
            calientaFinal = CARACTER_CALENTAR;                  // Animación de calentar
            temperaturaDestino = temperaturaCalentamientoFinal; // Temperatura que se ha de alcanzar, que depende el conmutador de selección
            break;
          case ESTADO_ENFRIANDO_FINAL :
            lcd.print(F("ENFRIANDO "));                   // Pone qué está haciendo
            subeBaja = CARACTER_ENFRIAR;                  // Animación de enfriar
            enfriaFinal = CARACTER_ENFRIAR;               // Animación de enfriar
            temperaturaDestino = MINIMO_ENFRIANDO_FINAL;  // Temperatura que se ha de alcanzar
            break;
          case ESTADO_ERROR_TEMPERATURA :       // Tanto en el estado ESTADO_ERROR_TEMPERATURA...
          case ESTADO_PAUSA_ERROR_TEMPERATURA : // ... como en el estado ESTADO_PAUSA_ERROR_TEMPERATURA
            if ((instanteActual / 500) & 1) {   // Se muestra parpadeando el mensaje de aviso
              lcd.print(F("SENSOR MAL"));
            }
            else {
              lcd.print(F("          "));
            }
            // Se va a mostrar la temperatura destino dependiendo del estado en que estaba la máquina de estado principal cuando ha fallado la temperatura
            switch (estadoGuardado) {
              case ESTADO_CALENTANDO_CICLO :
                temperaturaDestino = MAXIMO_CALENTANDO;
                break;
              case ESTADO_CALENTANDO_FINAL :
                temperaturaDestino = temperaturaCalentamientoFinal;
                break;
              case ESTADO_ENFRIANDO_CICLO :
                temperaturaDestino = MINIMO_ENFRIANDO;
                break;
              case ESTADO_ENFRIANDO_FINAL :
                temperaturaDestino = MINIMO_ENFRIANDO_FINAL;
              default :
                break;
            }
            break;
          case ESTADO_FINAL :
            // La máquina de estados principal ha finalizado
            estadoLCD = ESTADO_LCD_MUESTRA_FINAL; // La máquina de estados del LCD pasa a mostrar el mensaje final
            break;
        }
        // Muestra por qué ciclo va
        if (mostrarPasos) {
          lcd.setCursor(3 - (ciclo / 10), 1);
          lcd.print(ciclo);
          lcd.print('/');
          lcd.print(CANTIDAD_CICLOS);
          lcd.print('x');
        }
        // Muestra la temperatura destino
        lcd.setCursor(14, 1);
        lcd.print(temperaturaDestino);
        lcd.write(223);
        lcd.write(subeBaja);
        // Muestra la animación de la temperatura máxima del ciclo
        lcd.setCursor(0, 2);
        lcd.write(calientaCiclo);
        // Muestra la animación de la temperatura máxima del ciclo
        lcd.setCursor(8, 2);
        lcd.write(enfriaCiclo);
        // Muestra la temperatura máxima final (que puede variar)
        lcd.setCursor(0, 3);
        lcd.write(calientaFinal);
        lcd.print(temperaturaCalentamientoFinal);
        // Muestra la animación de la temperatura máxima del ciclo
        lcd.setCursor(8, 3);
        lcd.write(enfriaFinal);
      }
    case ESTADO_LCD_TEMPERATURA :
      // Muestra actualizado el valor de la temperatura
      lcd.setCursor(13, 0);
      if (temperaturaErronea) {
        lcd.print(F(" --.--")); // Es lo que muestra si la lectura de temperatura no es correcta
      }
      else {
        if ((temperatura < 100) && (temperatura > -10)) {
          lcd.write(' ');       // Pone el espacio para alinear la temperatura a la derecha
        }
        if ((temperatura < 10) && (temperatura >= 0)) {
          lcd.write(' ');       // Pone el espacio para alinear la temperatura a la derecha
        }
        lcd.print(temperatura);
      }
      lcd.write(223);
      break;
    case ESTADO_LCD_MUESTRA_FINAL :
      // Muestra el mensaje de finalización y pasa al estado ESTADO_LCD_TEMPERATURA
      lcd.clear();
      lcd.setCursor(3, 2);
      lcd.print(F("FIN DE PROCESO"));
      estadoLCD = ESTADO_LCD_TEMPERATURA;
      break;
  }
}

Las constantes que hay que “adaptar” son las mismas que las del código anterior. He cambiado un poco la animación de las flechas, me gusta más esta nueva versión. Aunque tal vez prefieras las otras animaciones y no las flechas. Ya me dirás por cuál te decantas, si usas este código o si no las cambias por otras que tú te hagas.

Hola ignoranteAbsoluto, tengo un problema con el nuevo código no copila me da error en el renglon 37.
(MAX6675 thermocouple(THERMO_CLK, THERMO_CS, THERMO_DO):wink: , error (max6675 does not mane a type), ("thermocouple" not declared in this scope). E intentando corregirlo yo, pero no e podido el código anterior si copila y casi es idéntico hasta ese renglón, así que recurro a usted para resolverlo con ayuda.
Saludos.

El problema creo que es que se me olvidó descomentar la primera línea de todas.

//#include "max6675.h"

Ha de quedar así:

#include "max6675.h"

Sin las dos barras del principio. Lo tenía comentado porque no tengo el sensor y tampoco tengo la librería esa instalada. Siento el contratiempo. Lo corrigo en el post.

1 Like

Hola ignoranteAbsoluto, lo revise infinidad de veces y no vi que estaba comentando el renglón de la librería max6675 necesito unos anteojos mas grandes.
Ya esta cargado y funcionando las flechas ahora coinciden con la función, mañana pruebo la alarma, con una sonda K que ya se que falla, al tocar el forro de malla tramada la temperatura se va a cero, a un qué esta a 50°, lo que estoy notando es que dentro de "calentando" la LCD se iluminan menos las letras que cuando esta en "enfriando", son mas brillantes, cosa que no afecta en nada la lectura o el funcionamiento.
Son mas de 85 renglones los que se necesitan para crear las flechas si estoy en lo correcto?, y si a mi también me parece mejor esta código que el anterior.
El lunes le comento como quedo, y seguro que mas de alguna pregunta.
Saludos

Hola, Ignorante Absoluto hasta hora fue posible probar el código en la deshidratadora, funciono muy bien, yo y mi equipo le estamos muy agradecidas por su ayuda. En un par de semanas ya no va a funcionar con resistencias eléctricas, sera con gas por razones de costo esperamos que el mismo codigo funcione como ahora
Saludos