Mi arduino se sale del Loop (Aparentemente)

Hola a todos, muchas gracias por la información que recibi de todos ustedes en post anterior. Esta vez algo raro esta pasando y me pregunto si tiene que ver con que me haya brincado algun truquito, o en que realidad soy muy malo programando =)

Bueno, larga historia corta, uso el arduino para controlar los ventiladores dentro de una camara de refrigeración. Esta dentro de mi tablero, como pueden ver. Tiene su fuente y sus relevadores.
La cosa es que asi de repente parece que se quedara "pegado".

Me explico; la subrutina void refrigeracion(); depende exclusivamente de que la variable termostato, este en HIGH... y le he visto con mis propios ojos... le medi 4.46V... por lo que debio entrar la subrutina.... me llamo la atencion, conecte mi celular, para ver que tiraba el serial (gracias Android)... y nada... nada de nada... sin mover ningun dato, oprimí el rest del arduino y voila... todo funciono normal.

Detalle extra... estuvo funcionando sin problemas por una semana.... despues comenzo a tirarse al rededor de las 5pm... tres dias consecutivos, en los que tuvo que ser reiniciado manualmente, y ahora por lo que me dicen... dura unas tres horas de operacion efectiva.

Ideas?
Quizas alguna variable?
Quizas el loop encuentra en una fraccion de segundo que no se cumplen
ninguna de las condiciones logicas?
Y como evitarlo??

Les dejo el código tal cual esta...

//TODAS LAS SALIDAS ESTAN INVERIDAS PARA PODER OPERAR LA TABLILLA DE RELAYS 
//EJEMPLO, SI NECESITO ENCENDER UN FOCO EN LUGAR DE 
// digitalWrite(focoDes, HIGH);
//ESCRIBIMOS; 
//digitalWrite(focoDes, LOW);
//DEBIDO A COMO OPERAN LOS RELEVADORES. 


// DECLARACION DE PINES A SER USADOS EN EL PROGRAMA 
int comp =13;                 // Pin para control del compresor 
int sol = 12;                 // pin para el control de la solenoide 
int motores[4] = {8,9,10,11}; //Pines controlar motores del difusor  
int focoRef= 6 ;              //Pin para encender el foco de la refrigeracion 
int focoDes= 5 ;              //Pin para encender el foco deshielo 
int Term = 4;                 //Pin para leer el estado del termostato 
int SW2 = 3;                  //pin para leer el switch principal
int SW1 = 2;                  //pin para leer el switch principal

//DECLARACION DE VARIABLES GLOBALES 
int Switch = 0;               //variable para almacenar el estado del switch 
int EdoSW1 = 0;
int EdoSW2 = 0;
int EdoTerm = 0;             //para alamcenear el estado del termostato 
int caso = 1;                //variable de 1 a 4 para alternar los motores difussor
boolean Encendido = false;   //Variable para comparar si se ha encendio o apagado el termostato


//            fila / columna                 
int ArrayMotores[6][4] ={{HIGH, HIGH, HIGH,  HIGH  } , //Primer arreglo de encendio de motores
                         {LOW,  HIGH, HIGH,  HIGH  } ,// Segundo... cada 1 y 0 corresponden a un motor
                         {HIGH, LOW , HIGH,  HIGH  } , //encendido o apagado. 
                         {HIGH, HIGH, LOW ,  HIGH  } , 
                         {HIGH, HIGH, HIGH,   LOW } ,
                         {LOW,  LOW,  LOW,   LOW } ,  
                          };

void setup(){
  Serial.begin(9600);
  pinMode(comp, OUTPUT); 
  pinMode(sol, OUTPUT); 
  pinMode(focoRef, OUTPUT); 
  pinMode(focoDes, OUTPUT); 
  pinMode(Term, INPUT); 
  pinMode(SW1, INPUT); 
  pinMode(SW2, INPUT);

  for(int b; b<4; b++){            //inicia contador de 1 a 4
    pinMode(motores[b], OUTPUT);   //declara cada motor como pin de salida 
    digitalWrite(motores[b], HIGH); //Apaga cada motor 
  }
}

void loop(){
EdoSW1 =  digitalRead(SW1); 
EdoSW2 =  digitalRead(SW2);

  if(EdoSW1 ==1 && EdoSW2 ==0){
     Switch=1; 
     }
     if(EdoSW1 ==0 && EdoSW2 ==1){
         Switch=2;
      } 
        if(EdoSW1 ==0 && EdoSW2 ==0){
          Switch =0; 
        }

  switch(Switch){
  case 0:
    Serial.println("El switch esta apagado"); 
    delay(200); //remover en la verson final 
    digitalWrite(focoRef, HIGH); 
    digitalWrite(focoDes, HIGH); 
    AllOff();
    break;

  case 1:
    Serial.println("El switch esta en refrigeracion"); 
    delay(200); //remover en la version final 
    digitalWrite(focoRef, HIGH); 
    digitalWrite(focoDes, LOW); 
    refrigeracion();
    break; 
    
  case 2:
    Serial.println("El switch esta en deshielo");   
    delay(200);// remover en la version final 
    digitalWrite(focoRef, LOW); 
    digitalWrite(focoDes, HIGH); 
    deshielo();  
    break;
  }
  delay(250);
}

// subrutina de deshielo, deja encendido solo los motores del evaporador. 
void deshielo(){ 
  digitalWrite(sol,LOW);  //enciende la solenoide 
  delay(1000); //remover en version final); 
  digitalWrite(comp, HIGH); //apaga el compresor
  delay(1000); //remover en version final

  for(int a; a<4 ; a++){
    digitalWrite(motores[a], ArrayMotores[5][a]); 
    delay(1000); 
  }
}


// subrutina para apagar todo; compresor, solenoide, evaporador. 
void AllOff(){
  digitalWrite(sol,HIGH);  //Apaga  la solenoide 
  delay(500);           //remover en version final); 
  digitalWrite(comp, HIGH); //apaga el compresor
  delay(200); //remover en version final
  for(int u; u<4; u++){
    digitalWrite(motores[u], ArrayMotores[0][u]);
  }  
}

//subrutina que encendera la refrigeracion y alternara los motores del 
//difusor.

void refrigeracion(){
  EdoTerm = digitalRead(Term); 
        
            if(caso >= 5){
            caso=1;}       
  
        if(EdoTerm == HIGH){
          digitalWrite(sol, HIGH);   //Apaga la solenoide, deja pasar liquido
           for(int d; d<4; d++){
              digitalWrite(motores[d], ArrayMotores[5][d]);
              delay(1000); 
              }
              delay(1000);               //retraso en la entrada del compresor
              digitalWrite(comp, LOW);  //enciende el compresor
              Serial.print("El termostato esta encendido  "); Serial.println(caso);
              Encendido = true; 
              }
           
      if(EdoTerm == LOW){
             if(Encendido == true){
             caso++;}
             Serial.print("El termostato esta apagado ");
             Serial.print("comienza subrutina"); Serial.println(caso);
             digitalWrite(sol, LOW);  //Enciende solenoide, no pasa liquido
             delay(1000);              //retraso en la entrada del compresor
             digitalWrite(comp, HIGH);  //Apaga el compresor
             for(int e; e<4; e++){
             digitalWrite(motores[e], ArrayMotores[caso][e]);
            }      
            Encendido = false; 
            }
}

Y algunas fotillos para que vean a que nos enfrentamos, en ellas esta el diagrama, combina los 5v del arduino con controles 220V etc etc..

Si lo requieren hago un video explicativo de que funciones realiza el pequeño aparato, aunque creo que esto es mas centrado en el codigo.. ::slight_smile:

Muchas gracias de antemano!!!!

Es mas que probable que se trate de un caso de ruido, pero para descartar problemas deberías ver si no se esta acabando la memoria de tu arduino por algún Bug. Para ello puedes usar la librería MemoryFree.h
agregando:

#include <MemoryFree.h> al principio y Serial.println(freeMemory()); en el loop .
No se debería producir cambios en la memoria.

Saludos

PeterKantTropus:
Es mas que probable que se trate de un caso de ruido, pero para descartar problemas deberías ver si no se esta acabando la memoria de tu arduino por algún Bug. Para ello puedes usar la librería MemoryFree.h
agregando:

#include <MemoryFree.h> al principio y Serial.println(freeMemory()); en el loop .
No se debería producir cambios en la memoria.

Saludos

Muchas gracias, haré la prueba como me lo indicas, de casualidad, tengo que dejar esas instrucciones en el programa final?

Puede ser que en algún momento no se cumpla con ninguna de los tres criterio lógicos? y necesite un else que reinicie el loop?.

Gracias!!!

Leyendo el post veo que te falta el caso que edoSw1 y edoSw2 ambos sean igual a 1 ¿ no se pueden dar al mismo tiempo ese caso?
una pequeña critica: evita utilizar palabras reservadas como variable. A pesar que es valido utilizar Switch con mayúscula como variable, puede dar lugar a equivocaciones.

Controla también la temperatura del armario donde se encuentra el arduino.

Saludos

Bueno, he agregado la librerria free memory en caso de que me permita ver que sucede.

Tambien he agregado;

if(EdoSW1 ==1 && EdoSW2 ==0){
     Switch=1; 
     }
     else if (EdoSW1 ==0 && EdoSW2 ==1){
         Switch=2;
      } 
     else if (EdoSW1 ==0 && EdoSW2 ==0){
          Switch =0; 
        }
        else(loop());

en caso de que por cualquier cosa, no tenga logica ninguno de esos estados... regresar al loop.. e intentarlo de nuevo.

Muchas gracias. les comento cualquier cosa.

PeterKantTropus:
Leyendo el post veo que te falta el caso que edoSw1 y edoSw2 ambos sean igual a 1 ¿ no se pueden dar al mismo tiempo ese caso?
una pequeña critica: evita utilizar palabras reservadas como variable. A pesar que es valido utilizar Switch con mayúscula como variable, puede dar lugar a equivocaciones.

Controla también la temperatura del armario donde se encuentra el arduino.

Saludos

Gracias, efectivamente, en teoria no se podria, ya que estos estados estan en un switch de tres posiciones, de manera que solo pueda existir uno de los dos en 1, o los dos en 0, sin emabrgo en la practica, parece que cualquier voltaje parasito, puede llegar a interpretarse como 1 y 1 ... en cuyo caso me imagino que el pregrama se detendria, que es justo lo que pasa.

Lo acabo de notar, por que despues de hacer las modificaciones arriba señaladas, la cargue en un UNO y lo instale, la primera vez todo magnifico, pero al reinicial los termicos generales, empezaron a activarse y apagarse varias cosas, me imagino que la subita subida de corriente indujo estados en los pines, y dio paso a este error, para evitarlo estoy agregando pequeñas pausas en el programa;

if(EdoSW1 ==1 && EdoSW2 ==0){
    delay(200); 
    Switch=1; 
     }
     else if (EdoSW1 ==0 && EdoSW2 ==1){
        delay(200); 
        Switch=2;
      } 
     else if (EdoSW1 ==0 && EdoSW2 ==0){
        delay(200);   
        Switch =0; 
        }
     else{
       delay(200);
       loop(); 
     }

Bueno, ire a probarlo y les mantengo informados, gracias.
Y si... procurare no usar palabras parecidas a las reservadas XD.
Saludos!!!!

Bueno, pues resulta que durante las 4 horas que estuvimos ahi, al pie del tablero, todo funciono normal todo funciono perfectamente, sin embargo unas 4 hr después, me llamaron que por que había habido una falla... al llegar... lo mas extraño, es que esta vez no solo todos los ventiladores estaban apagados, sino que tambien, el compresor estaba encendido...

A saber, el compresor, entra una linea y un delay despues de que todos los ventiladores se han encendido.

Ahora que he quitado que sea una lectura incorrecta de el SW, y que falle por un tercer estado logico...

Sera que falta... Serial.flush() ??? y se llena la memoria??
Intente conectar el serial cuando estaba en la falla... pero no pude leer nada... simplemente se detiene en algun punto...

Ahora en cuanto al hardware... tendra que ver que la tablilla de relays es alimentada de la misma fuente... recuerdo haber leído que habia un jumper para hacer que funcionara completamente optoisolada...

Alguna otra idea???

Gracias.

Tienes ruido, ruido y mas ruido.
Comiena mostrando como son las conexiones al Arduino de todas las entradas digitales.

Parece ser el caso.
Bueno, lo que me pides sería;

Pin 2 INPUT lee 5V del Switch principal
Pin 3 INPUT lee 5V del Switch principal
Pin 4 INPUT Lee 5v del termostato
Pin 5 OUTPUT enciente relevador del foco refrigeracion
Pin 6 OUTPUT enciende relevador del foco de deshielo

Pin 8 OUTPUT enciende relevador del motor 1
Pin 9 OUTPUT enciende relevador del motor 2
Pin 10 OUTPUT enciende relevador del motor 3
Pin 11 OUTPUT enciende relevador del motor 4
Pin 12 OUTPUT enciende relevador del compresor
Pin 13 OUTPUT enciende relevador del solenoide

Ahora bien del Pin 5 al 13... todos van a la tablilla de relevadores que se ubica a unos 5 cm del arduino. Son los cablesillos que se ven volando en la foto.

El pin 2 y 3... van a lo que es la tapa del gabinete, esos si pasan por unos 70cm entre otros cables
que pueden ser desde focos piloto 220V hasta alguna de las bonidas a 220 de los contactores.
Cre que se alcanzan a distinguir, un cable azul y uno amarillo en el manojo inferior de la tapa del gabinete, en alguna de las fotos.
Ambos cables tienen su resistencia a tierra para no dejar un voltaje flotante.

Ahora bien, cureseandole en el foro en este thread;
http://forum.arduino.cc/index.php?topic=119683.0

las entradas que no estén conectadas a ninguna lados las pongas en pullup o como salidas, principalmente para reducir consumo y ruido electrico (no es bueno dejar entradas flotantes en tecnología CMOS).

Eso tiene cierto sentido, pero no se hasta que punto el arduino se detenga o se salga del programa cuando recibe un voltaje o señal en los pines que no están siendo usados.
Ahora bien, algo interesante en el mismo hilo;

Yo lo he solucionado con un simple delay justo después de comprobara la entrada y acto seguido otra comprobación.

Adjunto trozo del código:

if(digitalRead (pullbano) == 0 ) {
delay (100);
if(digitalRead (pullbano) == 0 ) {

Quizás tambien falle la lectura de los pines, ya que por ejemplo; los 5V que lee el pin del termostato, pasan por un el contacto de un contacto, me imagino que dependiendo del caso, en el momento del cierre puede producirse un a variación en el voltaje que no sea ni 5V no 0V, pero no se como lo tomaría el arduino.

Creo que haré ese pequeño debounce que proponen en las tres lecturas, ademas de declarar los pines no usados como salidas. Curiosamente son los analogicos.

De cualquier manera espero me puedan dar mas ideas, para ir cerrandole el paso a esta falla tan extraña.

Gracias!!!!!

Bueno he hecho las modificaciones al codigo como quede, lo probe en una proto, y como es buena hora, ire a ponerlo, asi me da tiempo regresar a manual, en caso de que haya una falla en un rato.

Les dejo el codigo, a ver si le notan algo;

//TODAS LAS SALIDAS ESTAN INVERIDAS PARA PODER OPERAR LA TABLILLA DE RELAYS 
//EJEMPLO, SI NECESITO ENCENDER UN FOCO EN LUGAR DE 
// digitalWrite(focoDes, HIGH);
//ESCRIBIMOS; 
//digitalWrite(focoDes, LOW);
//DEBIDO A COMO OPERAN LOS RELEVADORES. 

//DECLARACION DE LIBRERIAS 
#include <MemoryFree.h>


// DECLARACION DE PINES A SER USADOS EN EL PROGRAMA 
int comp =13;                 // Pin para control del compresor 
int sol = 12;                 // pin para el control de la solenoide 
int motores[4] = {8,9,10,11}; //Pines controlar motores del difusor  
int focoRef= 5 ;              //Pin para encender el foco de la refrigeracion 
int focoDes= 6 ;              //Pin para encender el foco deshielo 
int Term = 4;                 //Pin para leer el estado del termostato 
int SW2 = 3;                  //pin para leer el switch principal
int SW1 = 2;                  //pin para leer el switch principal


//DECLARACION DE PINES QUE NO SERAN USADOS
int pinesNoUsados[6] ={A0, A1, A2, A3, A4, A5}; 

//DECLARACION DE VARIABLES GLOBALES 
int Switch = 0;               //variable para almacenar el estado del switch 
int EdoSW1 = 0;
int EdoSW2 = 0;
int EdoTerm = 0;             //para alamcenear el estado del termostato 
int caso = 1;                //variable de 1 a 4 para alternar los motores difussor
boolean Encendido = false;   //Variable para comparar si se ha encendio o apagado el termostato


//            fila / columna                 
int ArrayMotores[6][4] ={{HIGH, HIGH, HIGH,  HIGH  } , //Primer arreglo de encendio de motores
                         {LOW,  HIGH, HIGH,  HIGH  } ,// Segundo... cada 1 y 0 corresponden a un motor
                         {HIGH, LOW , HIGH,  HIGH  } , //encendido o apagado. 
                         {HIGH, HIGH, LOW ,  HIGH  } , 
                         {HIGH, HIGH, HIGH,   LOW } ,
                         {LOW,  LOW,  LOW,   LOW } ,  
                          };

void setup(){
  delay(500);
  Serial.begin(9600);
  pinMode(comp, OUTPUT); 
  pinMode(sol, OUTPUT); 
  pinMode(focoRef, OUTPUT); 
  pinMode(focoDes, OUTPUT); 
  pinMode(Term, INPUT); 
  pinMode(SW1, INPUT); 
  pinMode(SW2, INPUT);
  delay(250); 
  for(int b; b<4; b++){            //inicia contador de 1 a 4
    pinMode(motores[b], OUTPUT);   //declara cada motor como pin de salida 
    digitalWrite(motores[b], HIGH); //Apaga cada motor 
   }
 for(int z; z<5; z++){
   pinMode(pinesNoUsados[z], OUTPUT); //declara cada pin sin usar como salida 
   pinMode(pinesNoUsados[z], HIGH);   //pone cada pin no usado a 5V
   }
 delay(500); 
}

void loop(){
  Serial.print("freeMemory()=");
  Serial.println(freeMemory());
  delay(50);
  Serial.println("Inicia Lectura de SW"); 
  EdoSW1 =  digitalRead(SW1); 
  EdoSW2 =  digitalRead(SW2);

  if(EdoSW1 ==1 && EdoSW2 ==0){
    delay(100); 
    if(EdoSW1 ==1 && EdoSW2 ==0){
    Switch=1; 
     }}
     else if (EdoSW1 ==0 && EdoSW2 ==1){
        delay(100); 
        if (EdoSW1 ==0 && EdoSW2 ==1){
        Switch=2;
      }} 
     else if (EdoSW1 ==0 && EdoSW2 ==0){
        delay(100);   
        if(EdoSW1 ==0 && EdoSW2 ==0){
        Switch =0; 
        }}
     else{
       delay(200);
       loop(); 
     }

  Serial.println("Termina lectura de SW"); 
  delay(50); 
  Serial.flush();

  switch(Switch){
  case 0:
    Serial.println("SW apagado"); 
    delay(100); //remover en la verson final 
    digitalWrite(focoRef, HIGH); 
    digitalWrite(focoDes, HIGH); 
    AllOff();
    break;

  case 1:
    Serial.println("SW en refrigeracion"); 
    delay(100); //remover en la version final 
    digitalWrite(focoRef, HIGH); 
    digitalWrite(focoDes, LOW); 
    refrigeracion();
    break; 
    
  case 2:
    Serial.println("SW en deshielo");   
    delay(100);// remover en la version final 
    digitalWrite(focoRef, LOW); 
    digitalWrite(focoDes, HIGH); 
    deshielo();  
    break;
  }
  delay(150);
}

// subrutina de deshielo, deja encendido solo los motores del evaporador. 
void deshielo(){ 
  digitalWrite(sol,LOW);  //enciende la solenoide 
  delay(1000); //remover en version final); 
  digitalWrite(comp, HIGH); //apaga el compresor
  delay(1000); //remover en version final

  for(int a; a<4 ; a++){
    digitalWrite(motores[a], ArrayMotores[5][a]); 
    delay(1000); 
  }
}


// subrutina para apagar todo; compresor, solenoide, evaporador. 
void AllOff(){
  digitalWrite(sol,HIGH);  //Apaga  la solenoide 
  delay(500);           //remover en version final); 
  digitalWrite(comp, HIGH); //apaga el compresor
  delay(200); //remover en version final
  for(int u; u<4; u++){
    digitalWrite(motores[u], ArrayMotores[0][u]);
  }  
}

//subrutina que encendera la refrigeracion y alternara los motores del 
//difusor.

void refrigeracion(){
  EdoTerm = digitalRead(Term); 
        
            if(caso >= 5){
            caso=1;}       
  
        if(EdoTerm == HIGH){
          delay(100); 
          if(EdoTerm == HIGH){
          digitalWrite(sol, HIGH);   //Apaga la solenoide, deja pasar liquido
           for(int d; d<4; d++){
              digitalWrite(motores[d], ArrayMotores[5][d]);
              delay(1000); 
              }
              delay(1000);               //retraso en la entrada del compresor
              digitalWrite(comp, LOW);  //enciende el compresor
              Serial.print("Termostato encendido  "); Serial.println(caso);
              Encendido = true; 
              }}
           
      if(EdoTerm == LOW){
        delay(100); 
        if(EdoTerm == LOW){
             if(Encendido == true){
             caso++;}
             Serial.print("Termostato apagado ");
             Serial.print("Comienza subrutina "); Serial.println(caso);
             digitalWrite(sol, LOW);  //Enciende solenoide, no pasa liquido
             delay(1000);              //retraso en la entrada del compresor
             digitalWrite(comp, HIGH);  //Apaga el compresor
             for(int e; e<4; e++){
             digitalWrite(motores[e], ArrayMotores[caso][e]);
            }      
            Encendido = false; 
            }}
}

Asi mismo, por ahi acabo de leer que es mejor que la fuente de unos 9V a la entrada del arduino, la mia estaba rateada a 5V, me supongo que eso puede llevar a errores... no lo se todavia, intentare solo con el nuevo programa... ojala haya suerte.

Gracias.

Bueno, fui la instale y la probé y cual fue mi sorpresa cuando no funciono, nada de nada
no entraba al loop, no leia el SW... estuve un rato verifacando conexiones. Y nada... decepcionado de esta cosa
me traje la tarjeta q tiene los pulldowns de el switch de pres posiciones por que pense que tendria algun error y es que... al SW... si le llegaban los 5V,,, salían del otro lado del SW... 5V pero al llegar a donde se leen los pines me llegaban 2.0V... asi que no leia el ON... en fin la baje y cual fue mi sorpresa... el cable de tierra estaba roto... creo que esto hacia variar el estado del switch, en fin... mañana le re hare con cable flexible, por que esta cosa de alambre es muy frágil... espero que mejore.

Ya había funcionado una semana completa... :disappointed_relieved: :disappointed_relieved: :disappointed_relieved:

Tu sketch se comporta un poco raro, no digo que mal porque apenas lo analizo.
Veamos algunas cuestiones para poder ayudarte debidamente.

Todas serán preguntas eléctricas o electrónicas:
A. HARDWARE

  1. Alimentación del ARDUINO UNO
    1.1. Como alimentas el arduino? Esta es una pregunta muy importante. Intenta ser lo mas detalliasta posible. Todo lo que puedas decir de la fuente. Si es comprada indica el modelo como para investigar su comportamiento ante ruido de línea.
    1.2 Tienes filtros RFI en la entrada de la fuente?

  2. ENTRADAS DIGITALES
    2.1 como cableas las entradas desde los termostatos, Sw1 y 2. Usas cable común, cable con malla ?
    2.2 Usas optoacoplador a la entrada? VEO QUE NO según esquema eléctrico

  3. SALIDAS DIGITALES
    3.1 la salida del arduino es a través de optoacoplador si o no? VEO QUE NO según esquema eléctrico

  4. PUESTA A TIERRA
    Tienes una puesta a tierra para tu circuito?

OPTOACOPLADORES: por el momento olvidemos su uso. No harían gran cambio.
Si me preocupa el cableado.

B. SOFTWARE
Habia hecho una observación al rebote pero veo que si has tomado la precaución correspondiente.
Lo que no me gusta es el uso de delay, pero antes hay que resolver el problema de funcionamiento.

No entiendo para que vuelves a llamar a Loop() en este pasaje del código?

 if(EdoSW1 ==1 && EdoSW2 ==0){
    delay(100); 
    if(EdoSW1 ==1 && EdoSW2 ==0){
    Switch=1; 
     }}
     else if (EdoSW1 ==0 && EdoSW2 ==1){
        delay(100); 
        if (EdoSW1 ==0 && EdoSW2 ==1){
        Switch=2;
      }} 
     else if (EdoSW1 ==0 && EdoSW2 ==0){
        delay(100);   
        if(EdoSW1 ==0 && EdoSW2 ==0){
        Switch =0; 
        }}
     else{
       delay(200);
       loop();              // nunca habia visto esto 
     }

Posible error.
Se que te basaste en una rutina de otro HILO pero no siempre las cosas de otros hilos estan bien.
Yo no estoy de acuerdo con esto

 if(EdoSW1 ==1 && EdoSW2 ==0){
    delay(100); 
    if(EdoSW1 ==1 && EdoSW2 ==0){
    Switch=1; 
     }
}

mi interpretación de este código me dice lo siguiente.
Instante 0, leo Sw1 y Sw2, ok
Llego al if y pregunto sobre sus estados no importa cuales porque para el caso da lo mismo.
Supongomos son verdaderos los que copie y pegué o sea

EdoSW1 ==1 && EdoSW2 ==0
Luego del primer if viene un delay de 100mseg. Hasta ahi BIEN.
Pero luego vuelves a preguntar
si EdoSW1 ==1 && EdoSW2 ==0 y si en elprimero caso lo fueron en el segundo tambien.
No importa que pase, siempre lo serán. Porque? Porque no volvieron a leerse, son los mismos 100mseg atrás.
Entonces lo que está mal es el código del debounce.
Y por lo tanto, trabajando con contactores y con relés, con rebotes por doquier, no sabes nunca que está tomando el arduino como estado de esos u otros switches.
Ahora te sugiero una rutina debounce que mejore la situación pero sin delay.
La busco y la pego acá.

Efectivamente hay un detalle muy extraño, por que la primera ocasion, funciono perfectamente durante una semana completa, después daba un error cada 12 hr, despues cada 4... en fin.

A.HARDWARE
1.- La fuente es comprada. Una fuente swichada 110/220 a 5V con una salida maxima de acuerdo a lo que dice; 2.0A.
Me lei un poco y vi que la alimentacion recomendada para el UNO es de 9 a 12V... lo cual tiene
sentido ya que estabamos un poco abajo de los 5V en el retorno de algunos cables.
Hoy, pensando que ese sería una de las fallas, la he cambiado por otra fuente 110/220 9V 2.0A .
el unico cambio significativo fue que cambie el VCC de la tablilla de relay a la salida de 5V del
arduino.

1.2 No tengo filtros RFI en la salida de la fuente, crees que un par de capacitores de unos 4500uF estén bien?

2.1- Entradas digitales
Si hay tres cables comunes que van al switch... uno lleva 5V, los otros dos tienen una resitencia pull down en una tablilla adyacente. De esos dos cables, solo uno regresa con 5V a la vez, dando lugar a
tres estados; refrigeracion, apagado, deshielo.

2.2 No tengo optoacopladores.

3.- SALIDAS DIGITALES;
No tengo optoacopladores, del pin, se va directo al pin de control de la tablilla de relays de controles.

4.- Puesta a tierra.- En este apartado, quiero creer que me señalas una tierra física para el circuito, no no la tengo, solo la que sale de la fuente, que es comun entre el arduino y la tablilla de relays.

B. SOFTWARE.-
Debounce... intente implementarlo mediante un sencillo, codigo;

 if(EdoSW1 ==1 && EdoSW2 ==0){
    delay(100); 
    if(EdoSW1 ==1 && EdoSW2 ==0){
    Switch=1; 
     }}
     else if (EdoSW1 ==0 && EdoSW2 ==1){
        delay(100); 
        if (EdoSW1 ==0 && EdoSW2 ==1){
        Switch=2;
      }} 
     else if (EdoSW1 ==0 && EdoSW2 ==0){
        delay(100);   
        if(EdoSW1 ==0 && EdoSW2 ==0){
        Switch =0; 
        }}
     else{
       delay(200);
       loop(); 
     }

He leido que hay una biblioteca para este tipo de trabajos, me encontre estas dos;
https://www.pjrc.com/teensy/td_libs_Bounce.html

http://playground.arduino.cc/Code/Bounce

Sin embargo me parece un poco mas facil de usar la primera, salvo alguna otra sugerencia. creo que intentare implementar esa.

Muchas gracias, quedo en espera de tus observaciones e ideas, por que a mi francamente este problema ya me comienza a exasperar.

@surbyte

surbyte:
Tu sketch se comporta un poco raro, no digo que mal porque apenas lo analizo.
Veamos algunas cuestiones para poder ayudarte debidamente.

No entiendo para que vuelves a llamar a Loop() en este pasaje del código?

 if(EdoSW1 ==1 && EdoSW2 ==0){

delay(100);
    if(EdoSW1 ==1 && EdoSW2 ==0){
    Switch=1;
    }}
    else if (EdoSW1 ==0 && EdoSW2 ==1){
        delay(100);
        if (EdoSW1 ==0 && EdoSW2 ==1){
        Switch=2;
      }}
    else if (EdoSW1 ==0 && EdoSW2 ==0){
        delay(100); 
        if(EdoSW1 ==0 && EdoSW2 ==0){
        Switch =0;
        }}
    else{
      delay(200);
      loop();              // nunca habia visto esto
    }




Posible error.
Se que te basaste en una rutina de otro HILO pero no siempre las cosas de otros hilos estan bien.
Yo no estoy de acuerdo con esto



if(EdoSW1 ==1 && EdoSW2 ==0){
    delay(100);
    if(EdoSW1 ==1 && EdoSW2 ==0){
    Switch=1;
    }
}




mi interpretación de este código me dice lo siguiente.
Instante 0, leo Sw1 y Sw2, ok
Llego al if y pregunto sobre sus estados no importa cuales porque para el caso da lo mismo. 
Supongomos son verdaderos los que copie y pegué o sea

EdoSW1 ==1 && EdoSW2 ==0
Luego del primer if viene un delay de 100mseg. Hasta ahi BIEN.
Pero luego vuelves a preguntar 
si EdoSW1 ==1 && EdoSW2 ==0 y si en elprimero caso lo fueron en el segundo tambien.
No importa que pase, siempre lo serán. Porque? Porque no volvieron a leerse, son los mismos 100mseg atrás.
Entonces lo que está mal es el código del debounce.
Y por lo tanto, trabajando con contactores y con relés, con rebotes por doquier, no sabes nunca que está tomando el arduino como estado de esos u otros switches.
Ahora te sugiero una rutina debounce que mejore la situación pero sin delay.
La busco y la pego acá.

La llamada a loop es por que en cierto momento que conecte el monitor serial al arduino, no me devolvio nada, no se movía ni caminaba el programa, luego entonces pensé que quizás, algun voltaje parasito hubiera podido montarse en el cable que no deberia llevar voltaje, dando como resultado

EdoSW1 = 1, EdoSW2=1 , para lo cual no había ninguna opcion en el codigo, pudiendo ser que esto fuera lo que lo "trabara"... no tengo experiencia en caso que una cosa asi hubiera pasado, es por eso que pensé en que si no se cumplian con ninguno de los 3 estados definidos, se regresara al loop para hacer un nuevo intento.

//

Ahora bien, que me haces ver las cosas tienes toda la razón, esa doble "verificación" no es nada mas que repetir un error, ya que la medida de los pines se hace una vez y se asigna a la variable, paso seguido se compara por la rutina logica. Como bien dices, el detalle esta entonces en la lectura que se hace de los pines, ya que efectivamente... El estado del termostato se lee como sigue;

Un termostato digital a 220V, una vez que alcanza la temperatura de inicio"caliente"... cierra su contacto auxiliar, alimentando una bobina de un contactor. Entre dos de los NO del contactor estan respectivamente; Un VCC que viene de la fuente, y el cable con Pull Down a tierra que lleva la señal al pin que respectivamente lee el estado del termostato.

Bien, entonces dentro de los posibles errores el primero es que no tienes debounce. Asi que esperame un tiempo y te posteo una modificación con esa parte resuelta.
Luego veré que le ocurre al resto.
Eso de llamar al loop NOOOO DE NINGUNA MANERA. No se que implicancias puede tener pero no es para nada bueno.
Si tienes dudas del funcionamiento o del comportamiento y maneja tareas críticas que impliquen riesgo de algún tipo, lo que se hace es activar el watchdog del microcontrolador.

Yo uso una librería para manejar los switches que hace el debounce y algunas otras cosas mas.
Se llama Switch y mas abajo agregaré los archivos para que la agregues a tu libraries en el directorio Arduino de tu PC.

Switch.cpp (4.05 KB)

Switch.h (1.29 KB)

Hola, @surbyte, efectivamente ayer que me contaste los del debounce,me puse a buscar y me baje una libreria;

https://www.pjrc.com/teensy/td_libs_Bounce.html

De hecho es oficial de arduino, despues de algunos errores, por que siempre hay ejemplos poco claros, logre que el prorgrama compilara sin errores, lo cargue y lo probe en la proto, y aparentemente funciona.

Por cierto que alguien habia mencionado que el serial podia estar comiendose la memoria, y es cierto en una de las pruebas por error se quedo un }, que cerraba el loop antes del serial.flush() y efectivamente podias ver la memoria descender con cada iteracion.

Bueno agregado el debounce, te dejo el codigo, para que me digas que opinas;

//TODAS LAS SALIDAS ESTAN INVERIDAS PARA PODER OPERAR LA TABLILLA DE RELAYS 
//EJEMPLO, SI NECESITO ENCENDER UN FOCO EN LUGAR DE 
// digitalWrite(focoDes, HIGH);
//ESCRIBIMOS; 
//digitalWrite(focoDes, LOW);
//DEBIDO A COMO OPERAN LOS RELEVADORES. 

//DECLARACION DE LIBRERIAS 
#include <MemoryFree.h>
#include <Bounce2.h>

// DECLARACION DE PINES A SER USADOS EN EL PROGRAMA 
int sol = 13;                 // pin para el control de la solenoide 
int comp =12;                 // Pin para control del compresor 
int motores[4] = {8,9,10,11}; //Pines controlar motores del difusor  
int focoRef= 5 ;              //Pin para encender el foco de la refrigeracion 
int focoDes= 6 ;              //Pin para encender el foco deshielo 
int Term = 4;                 //Pin para leer el estado del termostato 
int SW2 = 3;                  //pin para leer el switch principal
int SW1 = 2;                  //pin para leer el switch principal


//DECLARACION DE PINES QUE NO SERAN USADOS
int pinesNoUsados[6] ={A0, A1, A2, A3, A4, A5}; 

//DECLARACION DE VARIABLES GLOBALES 
int Switch = 0;               //variable para almacenar el estado del switch 
                              //int EdoSW1 = 0;
                              //int EdoSW2 = 0;
//int EdoTerm = 0;             //para alamcenear el estado del termostato 
int caso = 1;                //variable de 1 a 4 para alternar los motores difussor
boolean Encendido = false;   //Variable para comparar si se ha encendio o apagado el termostato

Bounce EdoSW2 = Bounce(); 
Bounce EdoSW1 = Bounce(); 
Bounce EdoTerm = Bounce(); 

//            fila / columna                 
int ArrayMotores[6][4] ={{HIGH, HIGH, HIGH,  HIGH  } , //Primer arreglo de encendio de motores
                         {LOW,  HIGH, HIGH,  HIGH  } ,// Segundo... cada 1 y 0 corresponden a un motor
                         {HIGH, LOW , HIGH,  HIGH  } , //encendido o apagado. 
                         {HIGH, HIGH, LOW ,  HIGH  } , 
                         {HIGH, HIGH, HIGH,   LOW } ,
                         {LOW,  LOW,  LOW,   LOW } ,  
                          };

void setup(){
  delay(800);                      //Delay para prevenir ruido al arranque del arduino
  Serial.begin(9600);
  pinMode(comp, OUTPUT); 
  pinMode(sol, OUTPUT); 
  pinMode(focoRef, OUTPUT); 
  pinMode(focoDes, OUTPUT); 
  delay(250); 
  for(int b; b<4; b++){            //inicia contador de 1 a 4
    pinMode(motores[b], OUTPUT);   //declara cada motor como pin de salida 
    delay(500);
    digitalWrite(motores[b], HIGH); //Apaga cada motor 
   }
 for(int z; z<5; z++){
   pinMode(pinesNoUsados[z], OUTPUT); //declara cada pin sin usar como salida 
   pinMode(pinesNoUsados[z], HIGH);   //pone cada pin no usado a 5V
   }
  pinMode(SW1, INPUT);                //declara el pin como entrada 
    EdoSW1. attach(SW1);              //lo agrega a la instancia bounce llamada SW1
    EdoSW1. interval(150);            //da el intervalo del bounce 150ms 
 
  pinMode(SW2, INPUT);  
    EdoSW2. attach(SW2);
    EdoSW2. interval(150);

  pinMode(Term, INPUT); 
    EdoTerm. attach(Term);
    EdoTerm. interval(150);
  
  
 delay(500); 
}

void loop(){
  Serial.print("freeMemory()=");
  Serial.println(freeMemory());
  delay(50);
  Serial.println("Inicia Lectura de SW"); 
  EdoSW1.update(); 
         int ValSW1 = EdoSW1.read();
  EdoSW2.update();
         int ValSW2 = EdoSW2.read();


  Serial.print("ValSW1 = "); 
  Serial.println(ValSW1); 
  Serial.print("ValSW2 = "); 
  Serial.println(ValSW2); 

         
  if(ValSW1 ==HIGH && ValSW2 ==LOW){
    Switch=1; 
     }
     else if (ValSW1 ==LOW && ValSW2 ==HIGH){
        Switch=2;
      } 
     else if (ValSW1 ==LOW && ValSW2 ==LOW){
        Switch =0; 
        }
     
  Serial.println("Termina lectura de SW"); 
  delay(100); 

  switch(Switch){
  case 0:
    Serial.println("SW apagado"); 
    delay(100); //remover en la verson final 
    digitalWrite(focoRef, HIGH); 
    digitalWrite(focoDes, HIGH); 
    AllOff();
    break;

  case 1:
    Serial.println("SW en refrigeracion"); 
    delay(100); //remover en la version final 
    digitalWrite(focoRef, HIGH); 
    digitalWrite(focoDes, LOW); 
    refrigeracion();
    break; 
    
  case 2:
    Serial.println("SW en deshielo");   
    delay(100);// remover en la version final 
    digitalWrite(focoRef, LOW); 
    digitalWrite(focoDes, HIGH); 
    deshielo();  
    break;
  }
  delay(150);
  Serial.flush();
}

// subrutina de deshielo, deja encendido solo los motores del evaporador. 
void deshielo(){ 
  digitalWrite(sol,LOW);  //enciende la solenoide 
  delay(1000); //remover en version final); 
  digitalWrite(comp, HIGH); //apaga el compresor
  delay(1000); //remover en version final

  for(int a; a<4 ; a++){
    digitalWrite(motores[a], ArrayMotores[5][a]); 
    delay(1000); 
  }
}


// subrutina para apagar todo; compresor, solenoide, evaporador. 
void AllOff(){
  digitalWrite(sol,HIGH);  //Apaga  la solenoide 
  delay(500);           //remover en version final); 
  digitalWrite(comp, HIGH); //apaga el compresor
  delay(200); //remover en version final
  for(int u; u<4; u++){
    digitalWrite(motores[u], ArrayMotores[0][u]);
  }  
}

//subrutina que encendera la refrigeracion y alternara los motores del 
//difusor.

void refrigeracion(){
  EdoTerm.update();
   int  ValEdoTerm =EdoTerm.read(); 
        
            if(caso >= 5){
            caso=1;}       
  
        if(ValEdoTerm == HIGH){
           digitalWrite(sol, HIGH);   //Apaga la solenoide, deja pasar liquido
           for(int d; d<4; d++){
              digitalWrite(motores[d], ArrayMotores[5][d]);
              delay(1000); 
              }
              delay(1000);               //retraso en la entrada del compresor
              digitalWrite(comp, LOW);  //enciende el compresor
              Serial.print("Termostato encendido  "); Serial.println(caso);
              Encendido = true; 
              }
           
      if(ValEdoTerm == LOW){
             if(Encendido == true){
             caso++;}
             Serial.print("Termostato apagado ");
             Serial.print("Comienza subrutina "); Serial.println(caso);
             digitalWrite(sol, LOW);  //Enciende solenoide, no pasa liquido
             delay(1000);              //retraso en la entrada del compresor
             digitalWrite(comp, HIGH);  //Apaga el compresor
             for(int e; e<4; e++){
             digitalWrite(motores[e], ArrayMotores[caso][e]);
            }      
            Encendido = false; 
            }
}

Hoy cambiare el alambre que tenia en las tablillas, por cable que da mejor soldabilidad, y agregare
un capacitor de 470uF al positivo de la placa, para mejorar un poco la resistencia a pequeños espacios sin energía.

Pienso que me da tiempo instalarla hoy mismo y probarla realmente, regresare con fotos y observaciones, muchas gracias por tu ayuda.

En la tarde me bajo tu libreria a ver si es mas intuitiva que la que tengo.

Saludos!!!!

Espera dame unos minutos que te subo el programa modificado con la libreria que te sugerí.
Bueno incluye la librería sino no funciona.
Si miras la definición de la librería permite cualquier configuración para los switches.

// TODAS LAS SALIDAS ESTAN INVERIDAS PARA PODER OPERAR LA TABLILLA DE RELAYS 
// EJEMPLO, SI NECESITO ENCENDER UN FOCO EN LUGAR DE 
// digitalWrite(focoDes, HIGH);
// ESCRIBIMOS; 
// digitalWrite(focoDes, LOW);
// DEBIDO A COMO OPERAN LOS RELEVADORES. 

#if ARDUINO >= 100 
  #include "Arduino.h"
#else
  #include "WProgram.h"
#endif

//DECLARACION DE LIBRERIAS 
#include <MemoryFree.h>
#include "Switch.h"

// DECLARACION DE PINES A SER USADOS EN EL PROGRAMA 

const byte SW1		= 2;					//pin para leer el switch principal
const byte SW2		= 3;					//pin para leer el switch principal
const byte Term		= 4;					//Pin para leer el estado del termostato 

const byte focoRef	= 5 ;					//Pin para encender el foco de la refrigeracion 
const byte focoDes	= 6 ;					//Pin para encender el foco deshielo 

const byte motores[4] = {8,9,10,11};		//Pines controlar motores del difusor  

const byte sol		= 12;					// pin para el control de la solenoide 
const byte comp	=13;					// Pin para control del compresor 




//DECLARACION DE PINES QUE NO SERAN USADOS
const byte pinesNoUsados[6] ={A0, A1, A2, A3, A4, A5}; 

//DECLARACION DE VARIABLES GLOBALES 
int SWitches	= 0;               //variable para almacenar el estado del switch 
int caso		= 1;                //variable de 1 a 4 para alternar los motores difussor
boolean Encendido = false;   //Variable para comparar si se ha encendio o apagado el termostato


//            fila / columna                 
int ArrayMotores[6][4] ={{HIGH, HIGH, HIGH,  HIGH  } , //Primer arreglo de encendio de motores
                         {LOW,  HIGH, HIGH,  HIGH  } ,// Segundo... cada 1 y 0 corresponden a un motor
                         {HIGH, LOW , HIGH,  HIGH  } , //encendido o apagado. 
                         {HIGH, HIGH, LOW ,  HIGH  } , 
                         {HIGH, HIGH, HIGH,   LOW } ,
                         {LOW,  LOW,  LOW,   LOW } ,  
                          };

Switch EdoSW1	= Switch(SW1, INPUT, HIGH, 100); // button to VCC, 10k pull-down resistor, no internal pull-up resistor, HIGH polarity, 100mseg debounce
Switch EdoSW2	= Switch(SW2, INPUT, HIGH, 100); // button to VCC, 10k pull-down resistor, no internal pull-up resistor, HIGH polarity
Switch EdoTerm	= Switch(Term, INPUT, HIGH, 100); // button to VCC, 10k pull-down resistor, no internal pull-up resistor, HIGH polarity
boolean Status1 = false;
boolean Status2 = false;

void setup(){

  Serial.begin(9600);
  pinMode(comp, OUTPUT); 
  pinMode(sol, OUTPUT); 
  pinMode(focoRef, OUTPUT); 
  pinMode(focoDes, OUTPUT); 

  for(int b; b<4; b++){            //inicia contador de 1 a 4
    pinMode(motores[b], OUTPUT);   //declara cada motor como pin de salida 
    digitalWrite(motores[b], HIGH); //Apaga cada motor 
   }
 for(int z; z<5; z++){
   pinMode(pinesNoUsados[z], OUTPUT); //declara cada pin sin usar como salida 
   pinMode(pinesNoUsados[z], HIGH);   //pone cada pin no usado a 5V
   }
 delay(500); 
}

void loop() {

  //Serial.print("freeMemory()=");
  //Serial.println(freeMemory());

  //Serial.println("Leo SW"); 

  EdoSW1.poll();
  if (EdoSW1.on()) 
      Status1 = 1;
  else 
      Status1 = 0;

  Serial.print("\nSw1 =");
  Serial.print(Status1);

  EdoSW2.poll();
  if (EdoSW2.on()) 
     Status2 = 1;
  else 
     Status2 = 0;
	   
  Serial.print(" Sw2 =");
  Serial.print(Status2);	   
  SWitches = Status1 + (Status2 << 1);

  Serial.print("\n Switch =");
  Serial.println(SWitches);	   
  
  //Serial.flush();

  switch (SWitches) {
  case 0:
		Serial.println("SW apagado"); 
		digitalWrite(focoRef, HIGH); 
		digitalWrite(focoDes, HIGH); 
		AllOff();
		break;

  case 1:
		Serial.println("SW en refrigeracion"); 
		digitalWrite(focoRef, HIGH); 
		digitalWrite(focoDes, LOW); 
		refrigeracion();
		break; 
  case 2:
		Serial.println("SW en deshielo");   
		digitalWrite(focoRef, LOW); 
		digitalWrite(focoDes, HIGH); 
		deshielo();  
		break;
  }
  delay(150);
}

// subrutina de deshielo, deja encendido solo los motores del evaporador. 
void deshielo(){ 
  digitalWrite(sol,LOW);  //enciende la solenoide 
  delay(1000); //remover en version final); 
  digitalWrite(comp, HIGH); //apaga el compresor
  delay(1000); //remover en version final

  for (int a; a<4 ; a++) {
      digitalWrite(motores[a], ArrayMotores[5][a]); 
      delay(1000); 
  }
  Serial.println("Salgo de deshielo");
}


// subrutina para apagar todo; compresor, solenoide, evaporador. 
void AllOff(){
  digitalWrite(sol,HIGH);  //Apaga  la solenoide 
  delay(500);           //remover en version final 
  digitalWrite(comp, HIGH); //apaga el compresor
  delay(200); //remover en version final
  for (int u; u<4; u++){
      digitalWrite(motores[u], ArrayMotores[0][u]);
  }  
  Serial.println("Salgo de AllOFF");
}

//subrutina que encendera la refrigeracion y alternara los motores del difusor.

void refrigeracion(){
  
  //EdoTerm = digitalRead(Term); 
  EdoTerm.poll();
  
       
  if (caso >= 5){
     caso=1;
  }       
  
  if (EdoTerm.pushed()) {
     digitalWrite(sol, HIGH);   //Apaga la solenoide, deja pasar liquido
     for (int d; d<4; d++) {
         digitalWrite(motores[d], ArrayMotores[5][d]);
         delay(1000); 
     }
     delay(1000);               //retraso en la entrada del compresor
     digitalWrite(comp, LOW);  //enciende el compresor
     Serial.print("Termostato encendido  "); Serial.println(caso);
     Encendido = true; 
  }
           
  if (!EdoTerm.pushed()) {
     if (Encendido) 
		    caso++;

     Serial.print("Termostato apagado ");
     Serial.print("Comienza subrutina "); 
	 Serial.println(caso);
     digitalWrite(sol, LOW);  //Enciende solenoide, no pasa liquido
     delay(1000);              //retraso en la entrada del compresor
     digitalWrite(comp, HIGH);  //Apaga el compresor
     for (int e; e<4; e++){
		 digitalWrite(motores[e], ArrayMotores[caso][e]);
     }      
     Encendido = false; 
  }
  Serial.println("Salgo de refrigeracion");
}

Un par de comentarios para comprender que hice.
La librería maneja pulsadores e interruptores (tu caso) hay un set de comandos para uno y otro.
Para tu caso esta la funcion objeto.on() que te dice esi esta en 1 o no.

Siempre siempre hay que poner objeto.poll() para que haga lo que antes serìa Status = digitalRead(pin);
pero luego esta hecho internamente el debounce que es 100mseg en este caso.
Lo ves en la definición como esta

Switch EdoSW1	= Switch(SW1, INPUT, HIGH, 100); // button to VCC, 10k pull-down resistor, no internal pull-up resistor, HIGH polarity, 100mseg debounce

Ademas simplifiqué todo tus if en una suma de los estados de SW1 y SW2 desplazado a izq 1 posición. O sea que SW2 toma valores 2 o 0 que sumado a SW1 nos da 0,1,2,3

Yo cambiaría una cosa mas... los delay()
Los delay interrumpen el programa gastando tiempo y NO ATENDIENDO LOS SWITCHES.
Te lo pongo en mayúsculas porque es electrónicamente incorrecto usar eso en una instalación industrial.
No se que tan crítico es tu sistema, pero si reemplazas los delays por millis() el programa estará ejecutándose mas libremente, con la opción de poder tomar acciones intermedias si hicieran falta. Considéralo.

Ahora lo mas importante. Si todo funciona correctamente hasta acá quiero saber si has eliminado tu problema o no. Me refiero a los comportamientos erráticos que inidicaste al comienzo.
El funcionamiento de arduino en ambiente industrial es mi preocupación Nro 1, justamente por extraer experiencias que ayuden a mi conocimiento.

Bueno, pues le instale y despues de resolver algunos increibles problemas con el hardawe que tenia instalado, parece que se ha quedado funcionando, ahora bien he notado que si uno deja las pastillas de los contactores del compresor y los difusores encendidas durante el set-up del arduino;

Se encienden y apagan y luego se vuelven a encender, es como si se creara un ruido en los pines de lectura o algo similar, y tengo que apagarlo del general para no dañar partes importantes de la instalación.

Creo que es debido a esta parte del codigo;

for(int b; b<4; b++){            //inicia contador de 1 a 4
    pinMode(motores[b], OUTPUT);   //declara cada motor como pin de salida 
    delay(500);
    digitalWrite(motores[b], HIGH); //Apaga cada motor 
   }
 for(int z; z<5; z++){
   pinMode(pinesNoUsados[z], OUTPUT); //declara cada pin sin usar como salida 
   pinMode(pinesNoUsados[z], HIGH);   //pone cada pin no usado a 5V
   }

Lo que voy a hacer es quitar la parte donde se apaga cada elemento, ya que debido
a que estamos trabajando con la tablilla de relays, parece ser que se crea un circulo
vicioso en cuanto a ruido, o bajas de voltaje repentinas, simplemente esperaremos a que
la subrutina adecuada haga lo suyo.

Bueno, sin mas por el momento, espero a mañana para decirles como fue.

Gracias.

surbyte:
Espera dame unos minutos que te subo el programa modificado con la libreria que te sugerí.
Bueno incluye la librería sino no funciona.
Si miras la definición de la librería permite cualquier configuración para los switches.

Hola disculpame, no vi tu post me sali temprano y hasta ahora lo leo, es muy interesante el codigo que pones, y entiendo lo de los delays... No es mucho problema 3 o 4 segundos de retraso, mientras el programa efectue el enfriamiento, en ese tiempo la carne no alcanza a ganar ni 0.2°C, por lo tanto no es tan critico...

Ahora me leo tu codigo, y disculpa si hago algunas preguntas obvias, pero en realidad soy nuevo en esto de la programacion, todo lo que se lo he aprendido de internet, y a veces no muy bien aprendido como habras visto, bueno comenzare;

#if ARDUINO >= 100   // No entiendo esta seccion, pense que el # era para definir constantes
  #include "Arduino.h" // No sabia que se podian usar funciones .. que hace la libreria Arduino.h
#else
  #include "WProgram.h" //Que es Wprogram.h??? 
#endif

Usas bytes para que el programa sea mas liviano, me imagino?

// DECLARACION DE PINES A SER USADOS EN EL PROGRAMA 

const byte SW1 = 2; //pin para leer el switch principal  //
const byte SW2 = 3; //pin para leer el switch principal  //
const byte Term = 4; //Pin para leer el estado del termostato

Esta parte es similar al bounce de la otra libreria, señalamos un pin, declaramos si es INPUT o OUTPUT, y damos un tiempo para el debounce, Pero por que tienes solo dos booleanas para revisar el debounce, no faltaria una tercera para el tercer pin de entrada?

Switch EdoSW1 = Switch(SW1, INPUT, HIGH, 100); // button to VCC, 10k pull-down resistor, no internal pull-up resistor, HIGH polarity, 100mseg debounce
Switch EdoSW2 = Switch(SW2, INPUT, HIGH, 100); // button to VCC, 10k pull-down resistor, no internal pull-up resistor, HIGH polarity
Switch EdoTerm = Switch(Term, INPUT, HIGH, 100); // button to VCC, 10k pull-down resistor, no internal pull-up resistor, HIGH polarity
boolean Status1 = false;
boolean Status2 = false;
void setup(){

  Serial.begin(9600);
  pinMode(comp, OUTPUT); 
  pinMode(sol, OUTPUT); 
  pinMode(focoRef, OUTPUT); 
  pinMode(focoDes, OUTPUT); 

  for(int b; b<4; b++){            //inicia contador de 1 a 4
    pinMode(motores[b], OUTPUT);   //declara cada motor como pin de salida 
    digitalWrite(motores[b], HIGH); //Esta parte ya la removi por lo extraño que funciona.

Ahora lo mas importante. Si todo funciona correctamente hasta acá quiero saber si has eliminado tu problema o no. Me refiero a los comportamientos erráticos que inidicaste al comienzo.
El funcionamiento de arduino en ambiente industrial es mi preocupación Nro 1, justamente por extraer experiencias que ayuden a mi conocimiento.

Efectivamente el conocimiento de que es lo que esta pasando en este caso en particular es oro puro, para futuras experiencias de control industrial.

Por ahora me pasa de que esta funcionando la tablilla, espero que el debounce haga su trabajo correctamente, mañana de cualquier modo pinso ir a primera hora a ver como resulto todo, quiero retirar como ya te comente el HIGH de los relevadores que solo hace ruido. Sobre todo al reinicio ya que como ya te comente, cuando vi que comenzaba a encender y apagar erraticamente todo, pense de inmediato -Ahi esta el ruido- es por eso que por ahora pienso dejar los delay()... ya que si enciendo algo de potencia, como el compresor y sus 4HP, hay una variacion en el voltaje, y necesito que el arduino no este leyendo en ese momento sus pines.

Si todo va bien con esto, tengo planeado agregar 3 deshielos diarios, y una subrutina para que los ventiladores paren totalmente durante la noche, y una vez cada 15 min, alguno de ellos encienda por
digamos 5 min, solo para mantener actualizado el termostato.

La razon de hacer todo esto es evitar la oxidación de la carne por exceso de viento en la camara.

Bueno, desde ya comienzo a trabajar en esa subrutina y te la muestro, para que me digas que opinas.

Muchas gracias por tu colaboracion. :slight_smile:

Si el problema se resuelve cuenta con una explicacion mas detallada de cada uno de los sitemas y subsistemas, creo que es algo bastante interesante. 8)

larga respuesta.

No voy a copiar los comentarios anteriores porque quedaría un post muy grande, asi que espero me sigas. Yo iré punto a punto.

#if ARDUINO >= 100 // No entiendo esta seccion, pense que el # era para definir constantes
#include "Arduino.h" // No sabia que se podian usar funciones .. que hace la libreria Arduino.h
#else
#include "WProgram.h" //Que es Wprogram.h???
#endif

Olvidate de esto pero si no lo usamos no funciona bien la librería. ya lo intenté y no hay caso.
Es como una forma de hacer compatibles librerías viejas.

  1. Byte lo useo siempre para definir pines de entrada o salida. No hay mas de 0 a 255 valores de piens asi que suficiente con byte.

Pero por que tienes solo dos booleanas para revisar el debounce, no faltaria una tercera para el tercer pin de entrada?

Las dos booleanes las uso para establecer el valor de Switch que era tu variable con la que luego decides que hacer.
mira que yo sumo lo que leo de SW1 y SW2 y obtengo Switches (tuve que llamarla asi) porque generaba problema el nombre con la librería.

Por lo visto hasta ahi responde mas o menos tus consultas.
Lo que queda y me preocupa es la fuente del arduino.
La fuente del arduino debe tener filtros RFI a la entrada 220VAC y si es posible un nucleo de ferrite con el cable 220 dando vuelta por dentro. Núcleo cilíndrico y hueco por dentro.
si encuentro foto te la incluyo. Sino se compran tambien. Puede ser que para probar encuentres algun filtro en alguna fuente AT o ATX vieja o en deshuso. Sirven como para probar.

Si la fuente de alimentación la armaste tu, entonces un agregado importante es poner en el puente de diodos del secundario capacitores de 0.1 uF en paralelo con los diodos del puente.
Eso genera un camino para los transitorios directamente a tierra.
Son detalles improtantes y hay que evitar que lleguen al arduino.
Mira el post del PLC arduino que esta en Proyectos. Ahi postee una imagen de lo que te estoy comentando.
Servirá a tus necesidades.
NO OLVIDES LA PUESTA A TIERRA EXCLUSIVA para tu ARDUINO. NO agregues nada del sistema eléctrico a esta TIERRA, okay?
Motores su tierra.
Circuito electrico su tierra
Electrónica su tierra.

En un trabajo de un equipo de inspección de ensayo no destructivo tuve una debate con un ingeniero por este tema. El sostenía que una buena tierra para todo era suficiente.
Yo le hice ver el ruido eléctrico que generaban los motores y cuando pusimos tierras individuales desapareció todo. Debate ganado, pero mas importante fue la experiencia cuando vi una pureza en la Computadora cuando tomaba los datos. Fue algo maravilloso.
Entonces recuerda al menos una puesta a tierra de uso exclusivo para tu electronica y nada de compartir con el resto de la parte eléctrica. Soy reiterativo pero es fundamental.