Salir y continuar de blucle for

Hola foro, ya empece con la maquina de estados, y si funciona con mas estabilidad que el ciclo for, for while o switch case. Inicio con (unsigned paso previo;) encendí arduino con 26.5°, subió a 39° y apago el relePinA regreso a 36° y activo a relePinA. Si subo la temperatura a 42° se inicia (instanteAnterior) apaga relePinA, y entra en ciclo (bool enfriando = false;), termina el proceso apagando el relePinB al bajar a 29°, y termina el ciclo con, (enfriando = true;) y queda detenido arduino hasta que se reinicia.
Ahora solo hace falta que fluctué entre 36° y 39° 3 o 6 veces según se requiera, el ciclo (unsigned paso previo;) deshidrata los tomates de forma suave, la etapa (instanteAnterior) reduce la humedad al 5%, y luego (bool enfriando) los enfría en el punto exacto para el envasado, creando un vacío en el envase, al llegar a temperatura ambiente. Se me ocurre que puedo usar un bool para salir de pasoPrevio lo que no tengo ni idea es como repetir pasoprevio varias veces, con una maquina de estados.
saludos.

if (millis() - pasoPrevio > 250UL) {
    pasoPrevio = millis();
    temprelePinA = thermocouple.readCelsius();
    if ( temprelePinA > 39.00) {
      digitalWrite(relePinA,  HIGH);
    }
    // if (millis() - pasoPrevio > 250UL) {
    pasoPrevio = millis();
    temprelePinA = thermocouple.readCelsius();
    if ( temprelePinA < 36.00) {
      digitalWrite(relePinA,  LOW);
    }

No, el uso de millis() y de unsigened long intanteanterior; no es una máquina de estados. Deberías de documentarte un poco, o al menos leer los enlaces que puse en #13.

Por otro lado, al menos yo, no te puedo ayudar si no tengo claro qué es lo que tratas de hacer. En más de una ocasión he visto en este foro pidiendo ayuda para «poner» o «arreglar» un for, while, switch o cualquier cosa que se les ocurra. Cuando leo ese título ya intuyo que quien lo ha escrito se encuentra perdidísimo. Los problemas en programación no se suelen solucionar planteando «poner» una de esas cosas que he comentado. Es como si un médico pide ayuda a otro médico para que le diga cuál es la forma de administrar un antibiótico en vena a un paciente porque ya se lo ha dado por vía oral y no mejora. ¿No estará pasando que lo que padece el paciente no se cura con antibióticos? Un buen médico, ante la petición de ayuda de otro colega, lo primero que creo que haría sería preguntar por el paciente. Por su historial, los síntomas y tratamientos aplicados. Y con toda esa información estará en mejores condiciones para ayudar a su colega. Porque podría llegar a la misma conclusión y ayudar a pinchar al paciente o tal vez propondría otra prescripción para el caso.

Todo esto es para decirte que sería aconsejable que pusieras todo el código que has hecho hasta ahora, así como una detallada descripción de todo lo que tratas de hacer. Para ver si con ello logramos entender qué es lo que quieres y por dónde vas. Porque me temo que no tienes un problema puntual, sino un problema global. Un problema de planteamiento inicial, al no conocer cosas como las «famosas» máquinas de estados. Para empezar, te recomiendo que te leas Qué es y cómo funciona una máquina de estados ya que esto te puede dar una idea de en qué consite. Una vez tengas más o menos claro qué es la máquina de estados, el siguiente paso es tratar de identificar y enumerar los diferentes estados que ha de tener tu máquina, así como qué es lo que puede hacer que cambie de un estado a otro. El uso de los millis() no es más que una herramienta para poder usar el tiempo como una de las posibles cosas que hace que la máquina de estados cambie de estado.

Como ya he comentado, cuanto más claro y detallado expongas lo que quieres hacer, más fácil nos será ayudarte. Porque en este caso creo que no se trata de un problema puntual en tu código, sino de un problema de planteamiento inicial de todo el código.

Tus explicaciones de lo que tratas de hacer, no me dejan nada claro lo que pretendes.

Lo que creo haber entendido de cómo ha de funcionar es:

  • Al encenderse el arduino se enciende una resistencia de calentamiento y un ventilador. El ventilador ha de permanecer encendido hasta el final del secado, momento en que se ha de apagar.

  • En todo momento se toma la temperatura cada cierto tiempo (¿cada dos segundo y medio? No tengo claro cuánto) y se ha de mostrar en el LCD.

  • Paso 1: como la resistencia está encendida, sube la temperatura y se espera a que alcance los 39 grados. En el momento en que se alcanza, se apaga la resistencia.

  • Paso 2: como la resistencia está apagada, baja la temperatura y se espera a que alcance los 36 grados. En el momento en que se alcanza esa temperatura, se vuelve a encender la resistencia.

  • Se repite el paso 1 y paso 2 un número determinado de veces. (Que está por ver cómo se determina ese número de veces).

  • Después de haber realizado el paso 2 las veces que se indiquen, en lugar de pasar al paso 1 se pasa al paso 3

  • Paso 3: como la resistencia está encendida, se espera a que la temperatura llegue a 40 o 42 grados dependiendo de la posición de un interruptor conectado al pin 10.

  • Una vez alcanzada la temperatura del paso 3 se apaga la resistencia y se pasa al paso 4.

  • En el paso 4 se espera a que la temperatura sea inferior a 29 grados. Cuando la temperatura sea inferior a 29 grados se apaga el ventilador. Y se da por terminado el proceso.

¿Es este el comportamiento que se desea?

Nota: la enumeración de los pasos es orientativa y sólo para que nos entendamos.

¿Qué es eso de crear un vacío en el envase?

Lo dicho, si nos dejas bien claro qué es lo que quieres que haga el Arduino, te podremos ayudar mejor.

Hola ignorante absoluto, tu descripción de los pasos son correctos, eso es exactamente lo que quiero que haga arduino. En cuanto al punto exacto para el envasado, eso ya no tiene ninguna relación con el código. Es solo el efecto termodinámico de la expansión y contracción de los materiales, dependiendo de su temperatura todos los materiales se contraen al enfriar, menos el agua que se expande al congelarse, al meter un producto caliente en un envase sellado, al enfriarse se genera un vacío, que preserva mejor los alimentos.
Ya leí el enlace que me recomendó, tiene al menos 6 estados y 7 variables, 5 son botones y 2 sensores parece lenguaje arduino pero todo están en mayúsculas, y dice que no es lenguaje arduino que es un metalenguaje. Si me di una idea al igual que arduino usa if, else, case, while etcétera, hace un rato empece a buscar google, y veo cosas como emun, State, y que se pueden crear void antes de void setup dentro de void setup dentro del void loop, que se almacenan los estados, y con switch case se ejecutan los procesos, nada que ver con if (millis() - pasoPrevio > 250UL) { , hasta hora solo en conseguido un par que son específicos para idioma arduino.

Saludos.

No dejas claro que temperaturas se han de usar para definir los estados del Autómata de control.

Las lineas que tienes en tu programa y que se encargan de imprimir en el LCD las quitas de donde estan y las pones dentro de una función por ejemplo PRINT_LCD. En el lugar que ocupaban obiamente haces una llamada a esa función " PRINT_LCD (); " y en los dos while del for que te propuse, entre los parentesis finales llamas tambies a esa funcion :slight_smile:

while ( thermocouple.readCelsius() > 34.00) {PRINT_LCD ();}

Incluso podrias añadir mas informacion como en que vuelta del bucle for se encuentra, ( lcd.print (i); ), por ejemplo.
saludos.

Hola Gonpezzi, las temperaturas las ajusto en el código, de acuerdo con el tamaño o el tipo de fruta o verdura, de temporada, las que están en lo que he posteado son bajas, en relación a las usadas en el proceso real, estas temperaturas son para hacer las pruebas con un encendedor de cigarrillos, sobre una mesa.
Te explico usando los términos de ignorante absoluto, que me parece son mas claros que los míos. PASO1: inicia a temperatura ambiente la actual 29° releA (calefactor) encendido, releB (ventilador) encendido, al alcanzar 39°apaga releA PASO2: enciende releA a 34°, y se repite un determinado numero de veces ejemplo 3 o 6 veces, PASO3: como el releA esta encendido llegara a 40 o 42 según el estado del pin 10, una vez alcanzada la temperatura apaga el releA, PASO 4: al estar apagado el releA se enfría el producto hasta ser inferior de 29° y apaga el releB y aquí termina el ciclo.
saludos

Pues entonces no veo la necesidad de cambiar a una maquina de estados, tienes ya un programa bien codificado y que funciona bien, solo hay que añadirle lo del bucle for.
Creo que el bucle for que te propuse en el pst #14 funciona , solo que le faltaba la impresion en el sserial y LCD.
Prueba el siguiente codigo corregido segun te comente en el post #25, yo no tengo termo-par ni lcd-12c.


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

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

const byte thermoDO  = 6;
const byte thermoCS  = 5;
const byte thermoCLK = 4;

MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);
int i  = 0;
int boton = 10;
const byte vccPin     = 3;
const byte gndPin     = 2;
const byte gndPinf    = 8;
const byte vccPinr    = 9;
const byte relePinA   = 12;
const byte relePinB   = 13;
float temprelePinA;
float temprelePinB;
unsigned long instanteAnterior;
bool enfriando = false;
bool bucle = false;

void setup() {
  lcd.init();
  lcd.backlight();
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("D. Marmo Servicios"); // Mensaje a desplegar
  lcd.setCursor(0, 2);
  lcd.print("    Secadora Do 6 "); // Mensaje 2 a desplegar
  delay(3000); // espera 3 segundos con el mensaje estatico

  Serial.begin(9600);

  pinMode(vccPin, OUTPUT);
  digitalWrite(vccPin, HIGH);

  pinMode(gndPin, OUTPUT);
  digitalWrite(gndPin, LOW);

  pinMode(vccPinr, OUTPUT);
  digitalWrite(vccPinr, HIGH);

  pinMode(gndPinf, OUTPUT);
  digitalWrite(gndPinf, LOW);

  pinMode(relePinA, OUTPUT);
  pinMode(relePinB, OUTPUT);
  pinMode(boton, INPUT);
  Serial.println("temperatura  ");
  delay(3000);

}

void loop() {

  if (!bucle && thermocouple.readCelsius() > 39.00) { // en la subida se detecta 39 .Entramos en el for
    for (int i = 0; i < 3; i++) {
      digitalWrite(relePinA, HIGH); // apagamos la "calefaccion", empieza a bajar la temperatura
      while ( thermocouple.readCelsius() > 34.00) {// esperamos hasta que T = 34
        PRINT_LCD ("  Ciclo - " + String(i) + " ↓  ");
        Serial.print (" Ciclo - ");
        Serial.print (i);
        Serial.print (" ¡Bajando! T = ");
        Serial.print( thermocouple.readCelsius());
        Serial. println (" grados");
        delay (1000);
        PRINT_LCD ("  Temperatura   ");
        delay (1000);
      }
      digitalWrite(relePinA, LOW); // encendemos la calefacción
      while ( thermocouple.readCelsius() < 39.00) {// esperamos otra vez hasta llegar a los 39
        PRINT_LCD ("  Ciclo - " + String(i) + " ↑  ");
        Serial.print (" Ciclo - ");
        Serial.print (i);
        Serial.print (" ¡Subiendo! T = ");
        Serial.print( thermocouple.readCelsius());
        Serial. println (" grados");
        delay (1000);
        PRINT_LCD ("  Temperatura   ");
        delay (1000);
      }
      // se repite el ciclo i veces
    }
    bucle = true; // una vez finalizado el for bloqueamos futuras activaciones del for en la bajada final
  }
  // continua el programa subiendo hasta los 42 despues bajara hasta finalizar sin activar el for


  if (millis() - instanteAnterior > 2500UL) {
    instanteAnterior = millis();
    temprelePinA = thermocouple.readCelsius();

    Serial.println( thermocouple.readCelsius());
    if (enfriando == false) {
      PRINT_LCD (" Temperatura ↑  ");
    }
    else {
      PRINT_LCD (" Temperatura ↓  ");
    }
    Serial.println();

    if (temprelePinA > ((digitalRead(boton) == HIGH) ? 40.00 : 42.0)) {
      digitalWrite(relePinA, HIGH);

      enfriando = true;
    }
    if (enfriando) {
      if ( temprelePinA < 29.00) {
        digitalWrite(relePinB,  HIGH);
      }
    }
  }
}

// funcion Para imprimir en el LCD
// Se ha de llamar con el texto a representar en
// la primera linea de LCD con 16 caracteres
void PRINT_LCD (String linea) {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(linea);
  delay(500);
  lcd.setCursor(4, 2);
  lcd.print("C = " + String(temprelePinA));
  lcd.print((char)223);
}

Saludos.

Por lo que dices ahí, creo entender que tienes un conmutador conectados a tres pines del Arduino, el común al pin 10 como entrada y los otros dos contactos al pin 8 como salida a nivel bajo y al pin 9 como salida al nivel alto. Y esto es para que de una señal alta o baja al pin 10 en función de si la posición del conmutador está uniendo el común con el pin 8 o 9. :man_facepalming:

No es necesario malgastar dos pines para eso. En principio basta con que conectes sólo el común al pin 10 y los otros dos contactos a masa (GND) y 5 voltios (Vcc) respectivamente. Aunque también se puede hacer con un simple interruptor, aprovechando la resistencia interna pull-up que se puede activar en el pin de entrada. Para que entiendas qué es una resistencia pull-up y su necesidad, puedes ver Leer un pulsador con Arduino en la web de Luis Llamas. Aunque en la web habla de pulsadores, se aplica igualmente a interruptores (a efectos prácticos, la única diferencia entre un pulsador y un interruptor es que en este último no has de mantener el dedo encima de él para que permanezca en uno de los estados). Puedes utilizar tu conmutador como un interruptor conectando el común al pin 10 y uno de los otros dos contactos a masa (GND) y el otro dejándolo al aire (sin conectar a ningún lado). Sólo tienes que configurar el pin 10 como entrada con la resistencia pull-up interna activa. En una posición del interruptor (o conmutador) tendrás una lectura a nivel bajo (LOW) y en la otra una a nivel alto (HIGH).


pinMode(10, INPUT_PULLUP) // Esto configura el pin 10 como entrada y activa su resistencia pull-up interna

Una pregunta por curiosidad: ¿tan a menudo vas a cambiar la temperatura máxima del «último calentamiento» como para tener que poner ese conmutador? Porque por lo que has dicho, tienes pensado reprogramar el Arduino cada vez que vayas a cambiar de fruta. Y no sé si ese cambio de temperatura final (que ahora es de 40 o 42 grados) era un intento de ahorrarte tener que reprogramar el Arduino al inicio de cada temporada.

Yo, personalmente, me haría el programa de tal manera que pudiera parametrizar las temperaturas y el número de “ciclos intermedios” diréctamente en el Arduino con unos cuantos pulsadores, aprovechando que se dispone de una pantalla LCD de 20x4. ¿O me equivoco en lo del LCD?

Yo haría un menú que me permitiera elegir las temperaturas máximas y mínimas de los ciclos intermedio (39 y 36 grados, siguiendo como ejemplo lo que has dicho). Así como el número de veces que ha de hacer ese ciclo (1, 2, 3, 4, 5 o los que se quiera. Pudiendo ser incluso cero). Y por último la temperatura máxima que ha de alcanzar para el ciclo final. Siguiendo el ejemplo, habría que elegir una entre 40 o 42 grados, sin necesidad de utilizar el conmutador ya que si se quiere que para el siguiente secado sea distinto, basta con volver a ir al menú de configuración y ajustar la temperatura antes de iniciar el secado.

Más preguntas por curiosidad: ¿cuál es la temperatura máxima a la que podría llegar finalmente? ¿Hasta cuántos decimales quieres que se vea en el LCD al indicar la temperatura? Estas dos preguntas són más bien estéticas, para a la hora de diseñar la presentación de los datos, tener claro cuántos caracteres hay que reservar para mostrar la temperatura.

Otra pregunta más: ¿se va a tener que estar cambiando muy a menudo los ciclos de secado o sólo de vez en cuando, en el «inicio de temporada» que es cuando se cambia de producto?

Además del LCD, el conmutador, los dos relé y el sensor de temperatura, ¿hay conectado o se tiene pensado conectar algo más?

Hola ignoranteAbsoluto, respecto a las temperaturas, lo máximo posible en PASO:3, ternario alto 80°, ternario bajo 65°. PASO:1 máximo 55° PASO:2, 40° máximo. PASO: 1 y PASO:2, 12 repeticiones máximo, repeticiones mínimas 2. PASO: 4, 8° por encima de la temperatura ambiente que en esta región, fluctúa entre 20° y 28° en verano, estos parámetros son para tomate tipo saladet.
respecto al pin digital 10 ternario, originalmente le retiramos los pines al arduino, y le pusimos un conector molex de tres vías y cable blindado 2.60 mts. para evitar interferencias con el LCD ahora ya reubicamos el arduino y el conmutador de tres vías (ahora estan juntos ) 30 cm. y si es total mente viable usar la resistencia pull-up y usar esos metros de cable blindado para otra cosa.
En ocasiones tengo que cambiar los parámetros de temperatura en el codigo hasta tres veces por día, o 2 semanas sin hacer cambios, pero el ternario todos los días, muchas veces es de gran ayuda.

Hola gonpezzi, si es un buen programa, tiene su historia nace en youtube, con robojax, un miembro de este foro lo modifica para secar textiles, teñidos de forma artesanal, otro miembro de esta foro lo mejora con millis, un un amgo de la escuela lo modifico para controlar una bomba de agua que recircula agua caliente, yo lo use para remplazar la tarjeta dañada de una secadora de ropa de una compañera de la escuela, alguien mas lo usa para tostar café mi amiga Martha y yo la usamos para secar frutas y verduras aprovechando los bajos precios de excedentes de temporada (vivimos en una zona netamente agricola).
Cambiando de tema, estoy probando los cambios que le has echo al código, y esta funcionando en el banco de pruebas, el bucle for entra y sale, y se ve el estado del bucle en el LCD y monitor Serial, 0,1 y 2 y pasa al ternario, y a enfriando. E corrido el programa una docena de veces y sin falla, hasta el momento, lo monto mañana en la maquina, lo probare sin producto, que con tanta lluvia nadie a podido entrar a cosechar, sera brócoli la semana que viene.
Tengo mucho que aprender, ! && nunca los e usado, parece que uno niega y los otros son dos verdades, tampoco e visto PRINT_LCD en mayúsculas, y las flechas hacia arriba y hacia bajo, ni siquiera las encuentro en el teclado, como las escribiste ? por suerte se dejan copiar

Hola ignoranteAbsoluto, despues de leer sus comentarios si me parecen excelentes, seria un programa totalmente profesional, en las ultimas 24 horas es visto unos 20 códigos, elaborados con maquinas de estado, para controlar micro hondas, PCL, comunicación modbus RS485, lavadoras de ropa industriales, FPGAs, CNC, impresoras 3D, se usa la maquina de estado en una infinidad de equipos industriales, plataformas como Verilog usan la maquina de estados.
Compre un par de FPGAs una ciclón IV y una ciclón V para empezar a aprender a programarlas, y llego covid y tuve que abandonar la escuela, y sigo teniendo deseos de seguir aprendiendo programación por mi cuenta, y tu propuesta me ayudaría mucho a seguir aprendiendo.
Y si tenemos pensando hacer una deshidrata dadora de tambor. ya tengo un variador de frecuencia ABB de 1.5 hp bifásico y si tendría un tercer relé para controlar el variador es simple una señal HIGH para girar al derecha y una señal LOW girar a la izquierda con un intervalo en STOP entre giro y giro.
Ahora usamos un modulo relé de 2 canales y la idea era usar uno de 4 canales usar solo tres estando en HIGH igual que el ventilador, y otro Arduino y con el relé de 2 canales, hacer lo antes descrito, el tambor funciona el mismo tiempo que el ventilador, lo usaríamos para secar chile. No se como le llamen en tu país en ingles le llaman chili en Sudamérica aji picante.
En realidad todas tu ideas son buenas y son bienvenidas y puede estar seguro que se les dará un buen uso.
Saludos

Efectivamente && comprueba que ambas cosas a comparar sean verdad, el if solo se ejecutara cuando la temperatura sea >39 y el bucle no se haya ejecutado nunca, (periodo de calentamiento), como la variable bucle al principio se definio como false por eso va negada "!" , es lo mismo que si hubiera puesto:

if (bucle == false && thermocouple.readCelsius() > 39.00)

Al terminar el for la hago true y ya no repite el for en el periodo de secado.

Lo de las majusculas al definir la funcion es indiferente, puede ir en minusculas y darle el nombre que quieras siempre y cuando no coincida con el nombre de algun comando, variable, otra función, objeto creado por una libreria ... etc se comprueba facilmente: si al escribirlo te cambia de color , ojo algo no anda bien elige otro nombre, y en todo caso te daria un error en la compilacion indicandolo.

Lo de la flechita es simplemente codigo ASCII y se imprime pulsando la tecla "Alt" mas el numero correspondiente, al soltar la tecla "Alt" aparece el simbolo correspondiente, no nos damos cuenta pero al pulsar una tecla cualquiera nuestro ordenador la almacena
como un valor numerico de esa "tabla" ASCII. Para cada idioma existe una, para el nuestro suele ser la siguiente:


Saludos

Hola gatul, si estaba al rebes la temperatura. explicación: después de bucle for, entra al ternario y dependiendo del estado del pin 10 apaga el relePinA a 40° o 42° grados, y luego el ventilador enfría el producto hasta 29°, y y apaga el ventilador, y solo reiniciando el arduino vuelve a iniciar el ciclo completo.
Saludos.

gatul Karma: 1+
September 15

La verdad que ya me perdí.
Decías que no salía del for() pero si sale.
Ahora dices que no ejecuta el for() pero si mueve el relé, entonces si ejecuta el for().
No entiendo en definitiva que es lo que esperas que haga y te parece que no hace.

Tampoco entiendo lo que haces luego,

    if (temprelePinA > ((digitalRead(boton) == HIGH) ? 40.00 : 42.0)) { 
      digitalWrite(relePinA, HIGH); 

      enfriando = true;
    }
    if (enfriando) {
      if ( temprelePinA < 29.00) {
        digitalWrite(relePinB,  HIGH);  
      }
    }

No entiendo por qué cambias el rango de temperatura por el que pones relePinA en alto si para esas temperaturas ya estaría en alto cuando se ejecutó el for().
No veo una condición que ponga en bajo a relePinB, o sea, una vez que pasa a alto nunca más vuelve a bajo si no apagas el arduino.

Recuerda que puedes usar la consola para saber por donde anda el programa o controlar valores, simplemente haz que imprima por serial mensajes tipo "estoy en el for", "sali del for", "estoy dentro del 1er if".
Antes te lo hice imprimir en el lcd pero es mas practico usar la consola.

Saludos

Si esa función ternaria es bastante desconocida por lo que veo, pero funciona muy bien.
Saludos

gonpezzi
September 15

Hola.
Con este ultimo post aclaras muchas cosas que antes no veia. Creo que la eleccion del if dentro del for no es la adecuada y ademas creo que deberias añadir una variable que contenga si ya se ha ejecutado alguna vez dicho bucle, Yo lo haria mas o menos asi:

// inicio del bucle for
  if (!bucle && thermocouple.readCelsius() > 36.00) {
    for (int i = 0; i < 3; i++) {
      digitalWrite(relePinA, HIGH);
      while ( thermocouple.readCelsius() > 34.00) {}
      digitalWrite(relePinA, LOW);
      while ( thermocouple.readCelsius() < 36.00) {}
    }
    bucle = true;
  }
  // fin del bucle for

A, me podeis explicar que significa el "UL" en la sentencia

if (millis() - instanteAnterior > 2500UL)

Y que diablos hace esto:

if (temprelePinA > ((digitalRead(boton) == HIGH) ? 40.00 : 42.0))

No me he topado nunca con esos modificadores y por mas que busco no encuentro nada.
Saludos.

Ya lo estoy montando el Arduino con el código que modificaste y continua funcionando si falla la sonda K imprime sin aparecer caracteres raros al encender o apagar el motor
Saludos

gonpezzi
September 17

Pues entonces no veo la necesidad de cambiar a una maquina de estados, tienes ya un programa bien codificado y que funciona bien, solo hay que añadirle lo del bucle for.
Creo que el bucle for que te propuse en el pst #14 funciona , solo que le faltaba la impresion en el sserial y LCD.
Prueba el siguiente codigo corregido segun te comente en el post #25, yo no tengo termo-par ni lcd-12c.


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

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

const byte thermoDO  = 6;
const byte thermoCS  = 5;
const byte thermoCLK = 4;

MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);
int i  = 0;
int boton = 10;
const byte vccPin     = 3;
const byte gndPin     = 2;
const byte gndPinf    = 8;
const byte vccPinr    = 9;
const byte relePinA   = 12;
const byte relePinB   = 13;
float temprelePinA;
float temprelePinB;
unsigned long instanteAnterior;
bool enfriando = false;
bool bucle = false;

void setup() {
  lcd.init();
  lcd.backlight();
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("D. Marmo Servicios"); // Mensaje a desplegar
  lcd.setCursor(0, 2);
  lcd.print("    Secadora Do 6 "); // Mensaje 2 a desplegar
  delay(3000); // espera 3 segundos con el mensaje estatico

  Serial.begin(9600);

  pinMode(vccPin, OUTPUT);
  digitalWrite(vccPin, HIGH);

  pinMode(gndPin, OUTPUT);
  digitalWrite(gndPin, LOW);

  pinMode(vccPinr, OUTPUT);
  digitalWrite(vccPinr, HIGH);

  pinMode(gndPinf, OUTPUT);
  digitalWrite(gndPinf, LOW);

  pinMode(relePinA, OUTPUT);
  pinMode(relePinB, OUTPUT);
  pinMode(boton, INPUT);
  Serial.println("temperatura  ");
  delay(3000);

}

void loop() {

  if (!bucle && thermocouple.readCelsius() > 39.00) { // en la subida se detecta 39 .Entramos en el for
    for (int i = 0; i < 3; i++) {
      digitalWrite(relePinA, HIGH); // apagamos la "calefaccion", empieza a bajar la temperatura
      while ( thermocouple.readCelsius() > 34.00) {// esperamos hasta que T = 34
        PRINT_LCD ("  Ciclo - " + String(i) + " ↓  ");
        Serial.print (" Ciclo - ");
        Serial.print (i);
        Serial.print (" ¡Bajando! T = ");
        Serial.print( thermocouple.readCelsius());
        Serial. println (" grados");
        delay (1000);
        PRINT_LCD ("  Temperatura   ");
        delay (1000);
      }
      digitalWrite(relePinA, LOW); // encendemos la calefacción
      while ( thermocouple.readCelsius() < 39.00) {// esperamos otra vez hasta llegar a los 39
        PRINT_LCD ("  Ciclo - " + String(i) + " ↑  ");
        Serial.print (" Ciclo - ");
        Serial.print (i);
        Serial.print (" ¡Subiendo! T = ");
        Serial.print( thermocouple.readCelsius());
        Serial. println (" grados");
        delay (1000);
        PRINT_LCD ("  Temperatura   ");
        delay (1000);
      }
      // se repite el ciclo i veces
    }
    bucle = true; // una vez finalizado el for bloqueamos futuras activaciones del for en la bajada final
  }
  // continua el programa subiendo hasta los 42 despues bajara hasta finalizar sin activar el for

  if (millis() - instanteAnterior > 2500UL) {
    instanteAnterior = millis();
    temprelePinA = thermocouple.readCelsius();

    Serial.println( thermocouple.readCelsius());
    if (enfriando == false) {
      PRINT_LCD (" Temperatura ↑  ");
    }
    else {
      PRINT_LCD (" Temperatura ↓  ");
    }
    Serial.println();

    if (temprelePinA > ((digitalRead(boton) == HIGH) ? 40.00 : 42.0)) {
      digitalWrite(relePinA, HIGH);

      enfriando = true;
    }
    if (enfriando) {
      if ( temprelePinA < 29.00) {
        digitalWrite(relePinB,  HIGH);
      }
    }
  }
}

// funcion Para imprimir en el LCD
// Se ha de llamar con el texto a representar en
// la primera linea de LCD con 16 caracteres
void PRINT_LCD (String linea) {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(linea);
  delay(500);
  lcd.setCursor(4, 2);
  lcd.print("C = " + String(temprelePinA));
  lcd.print((char)223);
}

Saludos.

Hola Gonpezzi, espero y estes pasando un buen fin de semana.
Ya monte el arduino en la maquina deshidratadora, y tengo un problema con el LCD, al iniciar el ciclo for se congela, la impresión de temperatura, y en el monitor Serial funciona correctamente, el ciclo se sigue cumpliendo a la perfección, el releA se activa y desactiva conforma a las temperaturas establecidas, lo e probado con 6 ciclos, 12 ciclos y se cumplen bien.
Le agregue lcd.print(thermocouple.readcelsius()); debajo de, PRIN_LCD ( "Ciclo - " + String (i) + "sube"); y ahora se imprime en el LCD l "temperatura" lcd.setCursor(0,0);, y lcd.setCursor(0,2); imprime "c= 27.00° 36.50", el c=27.00 permanece congelada todo el ciclo for, y al terminar el ciclo for se activa C=27.00 actualizándose cada dos segundos, no cero que sea muy ortodoxa la solución pero funciona.
Cambie las flechas por sube y baja en el LCD porque se imprime una B deforme.
medio mucha pena se ven tan bonitas en el código.
Saludos.

 if (!bucle && thermocouple.readCelsius() > 39.00) { // en la subida se detecta 39 .Entramos en el for
    for (int i = 0; i < 3; i++) {
      digitalWrite(relePinA, HIGH); // apagamos la "calefacciona", empieza a bajar la temperatura
      while ( thermocouple.readCelsius() > 34.00) {// String esperamos hasta que T = 34
        PRINT_LCD ("  Ciclo - " + String (i) + " baja ");
        lcd.print( thermocouple.readCelsius());
        Serial.print (" Ciclo - ");
        Serial.print (i);
        Serial.print (" Bajando T = ");
        Serial.print( thermocouple.readCelsius());
        Serial. println (" grados");
        delay (1000);
        PRINT_LCD ("Temperatura");
        delay (2000);
      }
      digitalWrite(relePinA, LOW); // encendemos la calefacción
      while ( thermocouple.readCelsius() < 39.00) {// esperamos otra vez hasta llegar a los 39
        PRINT_LCD ("  Ciclo - " + String (i) + " sube ");
         lcd.print( thermocouple.readCelsius());
        Serial.print (" Ciclo - ");
        Serial.print (i);
        Serial.print (" Subiendo T = ");
        Serial.print( thermocouple.readCelsius());
        Serial. println (" grados");
        delay (1000);
        PRINT_LCD ("Temperatura");
        delay (2000);
      }
      // se repite el ciclo i veces
    }
    bucle = true; // una vez finalizado el for bloqueamos futuras activaciones del for en la bajada final
  }
  // continua el programa subiendo hasta los 42 despues bajara hasta finalizar sin activar el for

Si tienes razon en el congelamiento de la temperatura en el for, culpa mia en la funcion PRINT_LCD, no actualizo la variable temprelePinA. Cambia la funcion por esta otra:

void PRINT_LCD (String linea) {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(linea);
  delay(500);
  lcd.setCursor(4, 2);
  lcd.print("C = " + String (thermocouple.readCelsius()));
  lcd.print((char)223);
}

Y en cuanto a lo de la flechita es simplemente que la tabla de caracteres ASCCI de la libreria que usas no coincide exactamente con el normalizado, puedes probar con el "Alt" mas un numero del 0 al 254, lo mismo tienes suerte y te aparece con otro numero.
Saludos.

Tenés que buscar la hoja de datos del chip que maneja el display y fijarte en la tabla de caracteres del mismo si esos caracteres están definidos.
Por ej., yo tengo un 16x2 con chip HD44780 y las flechas arriba y abajo no están.

La solución es crear tus propios caracteres personalizados.
Para que tengas idea como se hace guiate por el Ejemplo 4 de este tutorial

Saludos

Hola gatul, ya vi su hoja de datos es modelo 2004A, con chip IC ST7066 al final de la hoja trae los caracteres admitidos y no parecen las flechas, ya vi el tutorial que me recomendaste y si puede ser útilpara otro proyecto, para este código prefiero usar el texto" baja sube" en lugar de flechas.
Saludos

Hola Gonpezzi, ya no se congela el LCD y le agregue despues de el ciclo ternario PRINT_LCD(" enfriando"); y después de digitalWrite (relePinB HIGH); PRINT_LCD(" proceso terminado");, Intentado sacarle el mayor provecho a la LCD.
Seguiré haciendo pruebas el resto del día.
Saludos