Fallo placa reles

Hola buenas a todos, he visitado este foro varias veces y me ha sacado de algunas dudas pero ahora hay algo que no encuentro y he decidido preguntar, seguro que a alguien ya le ha pasado.

Estoy con un proyecto para manejar una calefacción y he decidido utilizar Arduino, el esquema basico son 6 entradas y 8 salidas. Las entradas son los termostatos de cada zona de la casa mas el de agua caliente, y las salidas son bombas electrovalvulas etc.

El problema es que he conectado todo de todas las formas posibles, con distintas fuentes de alimentacion incluida la pila a 9v y la placa se vuelve loca, la placa de reles produce un rateo (le llamo asi a cuando los reles hacen un ruido de prrrrrrrrr constante, como si entrasen y saliesen mil veces por segundo) y solo se "cura" cuando la enchufo al pc, le cargo el programa y hago pruebas estando enchufada al pc, es decir cojo los 5v de su salida y los voy metiendo a los pines de entrada, estando la placa reles tambien echufada a esa salida de 5v y asi si funciona bien.

Entiendo bastante de electricidad y no hay ningun problema de conexion ni de voltajes, no se que esta pasando.
Os dejo una foto para que veais el cuadro guapo que esta quedando y si me podeis echar un cable aqui estare yo tambien para cualquier cosa.

Muchas gracias por leerlo y un saludo!!

Adjunto otra tambien haciendo pruebas que no todo es tan bonito como parece jaja

Parece que estás experimentando problemas de suministro de energía y conexión a tierra. Cuando el Arduino está alimentado a través del USB del PC, obtiene una fuente de alimentación de 5V estable y una conexión a tierra común, lo que probablemente explica por qué funciona perfectamente. Pero al usar fuentes de alimentación externas, surgen problemas, probablemente debido a ruido, corriente insuficiente o problemas de conexión a tierra.

Aquí tienes algunos consejos para solucionar tu problema y estabilizar el sistema:

1. Estabilidad del suministro de energía

  • Asegúrate de que la fuente de alimentación externa pueda proporcionar suficiente corriente tanto para el Arduino como para la placa de relés. Los relés pueden consumir bastante corriente, y si la fuente no puede satisfacer la demanda, puedes experimentar problemas como el ruido rápido de conmutación de los relés (el "prrrrrr").
  • Si estás usando una batería de 9V, puede que no tenga la capacidad suficiente para alimentar los relés. Considera usar una fuente de alimentación de corriente continua más robusta de 5V o 12V con suficiente amperaje (dependiendo de los relés y el Arduino).

2. Alimentar los relés por separado

  • En lugar de alimentar la placa de relés directamente desde el pin de 5V del Arduino, intenta alimentarla por separado con su propia fuente de alimentación de 5V, asegurándote de que la tierra del Arduino y la de la fuente de alimentación de los relés estén conectadas.

3. Capacitores de desacoplamiento

  • Coloca capacitores de desacoplamiento (100µF y 100nF en paralelo) cerca de las entradas de alimentación del Arduino y la placa de relés para suavizar las fluctuaciones de voltaje. Esto puede ayudar a eliminar el ruido en el circuito.

4. Problemas de conexión a tierra

  • Asegúrate de tener una conexión a tierra común sólida entre todos los componentes (Arduino, relés, sensores, etc.). Una tierra flotante o una conexión a tierra incorrecta puede causar un comportamiento errático, especialmente con componentes digitales.

5. Diodos de protección en los relés

  • Si aún no lo has hecho, coloca diodos de protección ("flyback") (por ejemplo, 1N4007) en paralelo con las bobinas de los relés para proteger al Arduino de picos de voltaje causados cuando los relés se desenergizan. Esto ayudará a reducir las interferencias que podrían estar causando las conmutaciones incorrectas.

6. Aislamiento con optoacopladores

  • Si tu placa de relés tiene optoacopladores, asegúrate de estar usándolos correctamente. Los optoacopladores pueden proporcionar aislamiento eléctrico entre el lado de control (Arduino) y el lado de potencia (relés), lo que puede ayudar si hay interferencias o ruido por la conmutación de los relés.

7. Revisa las conexiones

  • Verifica todas tus conexiones, especialmente entre los relés y el Arduino, para asegurarte de que no haya conexiones flojas o inestables que puedan causar comportamientos erráticos. Considera usar una protoboard o conectores con terminales de tornillo para asegurar mejor las conexiones.

8. Usar alimentación externa para el Arduino

  • Si es posible, intenta usar una fuente de alimentación externa para el Arduino, como un adaptador regulado de 5V o 9V, en lugar de solo el USB. Esto suele proporcionar más estabilidad que una batería de 9V, que puede no entregar un voltaje constante bajo carga.

Si puedes compartir más detalles sobre el modelo de tu placa de relés y cómo tienes todo conectado, puedo darte un consejo más específico.

Cada relé puede consumir hasta 80 mA cuando se activa. Parece que tienes alrededor de ocho relés. Por lo tanto, necesitas una fuente de alimentación que pueda generar al menos 640 mA. Mejor aún, consigue una fuente de alimentación de 1 amperio para que te sobre.

1 Like

Antes de nada decir que no es un Arduino como tal sino una copia marca GEEKCREIT que en teoria es equivalente a Arduino UNO.

Puede que si sea algo de ruidos porque lo hace el 90% de las veces pero alguna que otra no lo hace, llevo una semana probando y ese 90% pueden ser unas 200 veces.
Probare eso que dices de los capacitores y muchas gracias por esa respuesta tan currada.

Dejo aqui mas fotos y 5 esquemas aunque he probado mas para que se vea que he probado lo basico y sigue igual. La fuente que uso es de 5Vdc 2A, no deberia tener problema.







¿Qué está haciendo el ruido? El ruido no es bueno en la mayoría de los circuitos, ya que introduce inconsistencias y, por lo tanto, muchos problemas. Tal vez podamos encontrar una manera de limitar o eliminar el ruido. Si es una entrada flotante en algún lugar, podemos conectarla a un nivel alto o bajo con una resistencia, pull up o pull down.
Una cosa que he notado en tu esquema es que parece que estás alimentando el Arduino desde 5v en el pin VIN y los relés desde el pin 5v de Arduino. Esa no es una buena idea.
No deberías suministrar menos de 7v al pin VIN.
Y definitivamente nunca deberías alimentar tantos relés desde el pin 5v de Arduino. Si la fuente de alimentación de 5v 2A está bien regulada, puedes omitir el pin VIN por completo y conectar los relés directamente a la fuente de alimentación externa también. ¡Eso elimina ambos problemas a la vez!

Tampoco deberías tener dos fuentes de alimentación conectadas a un Arduino al mismo tiempo. Solo se necesita una. Por lo tanto, tal vez sea mejor quitar el USB y usar solo la fuente de alimentación de 5 V y 2 A. Puedes dañar un Arduino si usas dos fuentes de alimentación a la vez.

Pido disculpas si mi español no es perfecto, el inglés es mi primera lengua.

No uses nunca baterias de 9V para estas cosas. Solo le das de comer a quien te la vende.
El consejo de @outbackhut no solo es preciso sino muy claro.

En todo esto no has puesto tu código y no podemos saber si el ruido es tal o simplemente tu código esta mal y le estas diciendo que prenda apague de tal modo que se escuche esa acción multiplicada por 8.
Hay que ser cuidadoso a la hora de programar.
Agrega tu código usando etiquetas.

1 Like

¿Cúal es la función de los relés externos que hay en el armario? ¿Estás activando dichos relés con los relés del módulo?¿Cúal es la potencia de las bombas de la calefacción?

Gracias por contestar, dejo aqui el codigo creo que esta bastante limpio aunque no soy ni de lejos un experto en esto de electronica y mucho menos de arduino, es mi primer proyecto con el y no se ni por donde me vienen.

PROGRAMA arduino.pdf (264,6 KB)

1 Like

Un gran número de usuarios de este foro no descargan un PDF para leer su código. Apreciaríamos mucho si pudieran volver a publicar ese código en las etiquetas de código como lo solicitan las instrucciones del foro. ¡Gracias!

Hola, esos reles externos son para dar señales de entrada al arduino, ya que sus entradas son termostatos que hay por casa y en los depositos de agua asique lo que hago es lo siguiente: llevo una fase de 220v a cada termostato y su vuelta me activa la bobina del rele, entonces tengo conectado al comun del rele una señal de 5v que sale de la parte de potencia de arduino, y con el normalmente abierto del rele lo conecto al pin que corresponda para ese termostato. Asique no, no estoy activando esos reles con el modulo.
La potencia de las bombas es pequeña, 300w a tope entre las dos, pero eso no deberia influir porque simplemente pasan por el contacto del rele.
Muchas gracias por contestar un saludo





Lo siento no me deja pegarlo, he subido unas capturas del pdf

Dos de nosotros hemos solicitado que ingrese su código en las etiquetas de código. Esto no son etiquetas de código. Lea las instrucciones de mi último mensaje.

¿A qué te refieres con que no te deja pegarlo?

// Definimos los pines para los termostatos
#define T1_PIN 2 // Chimenea
#define T2_PIN 3 // ACS (ON/OFF)
#define T3_PIN 4 // Inercia (ON/OFF)
#define T4_PIN 5 // Suelo radiante
#define T5_PIN 6 // Planta 1º
#define T6_PIN 7 // Planta 2º

// Definimos los pines para las electroválvulas y bombas
#define EV1_PIN 8 // ACS-Inercia
#define EV2_PIN 9 // Calefacción-Disipador
#define EV3_PIN 10 // Zona suelo radiante
#define EV4_PIN 11 // Zona planta 1º
#define EV5_PIN 12 // Zona planta 2º
#define B1_PIN 13 // Bomba circuíto Primario
#define B2_PIN A0 // Bomba circuíto Secundario
#define AERO_PIN A1 // Contacto para Aerotermia

void setup() {
// Configuración de pines como entrada
pinMode(T1_PIN, INPUT);
pinMode(T2_PIN, INPUT);
pinMode(T3_PIN, INPUT);
pinMode(T4_PIN, INPUT);
pinMode(T5_PIN, INPUT);
pinMode(T6_PIN, INPUT);

// Configuración de pines como salida
pinMode(EV1_PIN, OUTPUT);
pinMode(EV2_PIN, OUTPUT);
pinMode(EV3_PIN, OUTPUT);
pinMode(EV4_PIN, OUTPUT);
pinMode(EV5_PIN, OUTPUT);
pinMode(B1_PIN, OUTPUT);
pinMode(B2_PIN, OUTPUT);
pinMode(AERO_PIN, OUTPUT);

// Inicializamos todo en apagado
digitalWrite(EV1_PIN, LOW);
digitalWrite(EV2_PIN, LOW);
digitalWrite(EV3_PIN, LOW);
digitalWrite(EV4_PIN, LOW);
digitalWrite(EV5_PIN, LOW);
digitalWrite(B1_PIN, LOW);
digitalWrite(B2_PIN, LOW);
digitalWrite(AERO_PIN, LOW);
}

void loop() {
// Leemos los estados de los termostatos
bool T1 = digitalRead(T1_PIN);
bool T2 = digitalRead(T2_PIN);
bool T3 = digitalRead(T3_PIN);
bool T4 = digitalRead(T4_PIN);
bool T5 = digitalRead(T5_PIN);
bool T6 = digitalRead(T6_PIN);

// Estado de las válvulas de zona (según los termostatos)
bool EV3 = T4;
bool EV4 = T5;
bool EV5 = T6;

// Verificación constante: si T4, T5 o T6 están apagados, las EV correspondientes se apagan
if (!T4) digitalWrite(EV3_PIN, LOW); // Apaga EV3 si T4 está apagado
if (!T5) digitalWrite(EV4_PIN, LOW); // Apaga EV4 si T5 está apagado
if (!T6) digitalWrite(EV5_PIN, LOW); // Apaga EV5 si T6 está apagado

// Sin demanda de ACS ni calefacción: todo apagado
if (!T2 && !(EV3 || EV4 || EV5)) {
if (T1) {
// T1=ON, T2=OFF, EV3=EV4=EV5=OFF
// Chimenea encendida, todo en temperatura
digitalWrite(EV1_PIN, LOW); // EV1 hacia inercia
digitalWrite(EV2_PIN, LOW); // EV2 hacia disipador
digitalWrite(B1_PIN, HIGH); // Enciende B1
digitalWrite(B2_PIN, HIGH); // Enciende B2
} else {
// T1=OFF, T2=OFF, sin demanda de calor
digitalWrite(EV1_PIN, LOW); // EV1 en inercia
digitalWrite(EV2_PIN, LOW); // EV2 en disipador
digitalWrite(B1_PIN, LOW); // Apaga B1
digitalWrite(B2_PIN, LOW); // Apaga B2
digitalWrite(AERO_PIN, LOW); // Apaga aerotermia
}
}

// Demanda de ACS sin calefacción
if (T2 && !(EV3 || EV4 || EV5)) {
if (T1) {
// T2=ON, T1=ON, ACS demandado
digitalWrite(EV1_PIN, HIGH); // EV1 hacia ACS
digitalWrite(B1_PIN, HIGH); // Enciende B1
digitalWrite(B2_PIN, LOW); // Apaga B2
digitalWrite(EV2_PIN, LOW); // EV2 en disipador (por seguridad)
digitalWrite(AERO_PIN, LOW); // Apaga aerotermia
} else {
// T2=ON, T1=OFF, ACS demandado pero sin chimenea
digitalWrite(AERO_PIN, HIGH); // Activa aerotermia
digitalWrite(EV1_PIN, HIGH); // EV1 hacia ACS
digitalWrite(B1_PIN, LOW); // Apaga B1
digitalWrite(B2_PIN, LOW); // Apaga B2
digitalWrite(EV2_PIN, LOW); // EV2 en disipador
}
}

// Demanda de calefacción sin ACS
if (!T2 && (EV3 || EV4 || EV5)) {
// Ignorar T3 ya que hay demanda de los termostatos de zona
if (T1) {
// T2=OFF, T1=ON, Calefacción demandada
digitalWrite(EV1_PIN, LOW); // EV1 hacia inercia
digitalWrite(EV2_PIN, HIGH); // EV2 hacia calefacción
digitalWrite(B1_PIN, HIGH); // Enciende B1
digitalWrite(B2_PIN, HIGH); // Enciende B2
digitalWrite(EV3_PIN, EV3); // Abre EV3 según T4
digitalWrite(EV4_PIN, EV4); // Abre EV4 según T5
digitalWrite(EV5_PIN, EV5); // Abre EV5 según T6
digitalWrite(AERO_PIN, LOW); // Apaga aerotermia
} else {
// T2=OFF, T1=OFF, Calefacción con aerotermia
digitalWrite(AERO_PIN, HIGH); // Activa aerotermia
digitalWrite(EV1_PIN, LOW); // EV1 hacia inercia
digitalWrite(EV2_PIN, HIGH); // EV2 hacia calefacción
digitalWrite(B1_PIN, LOW); // Apaga B1
digitalWrite(B2_PIN, HIGH); // Enciende B2
digitalWrite(EV3_PIN, EV3); // Abre EV3 según T4
digitalWrite(EV4_PIN, EV4); // Abre EV4 según T5
digitalWrite(EV5_PIN, EV5); // Abre EV5 según T6
}
}

// Demanda de ACS y calefacción simultáneamente
if (T2 && (EV3 || EV4 || EV5)) {
if (T1) {
// T2=ON, T1=ON, Demanda simultánea de ACS y calefacción
digitalWrite(EV1_PIN, HIGH); // EV1 hacia ACS
digitalWrite(B1_PIN, HIGH); // Enciende B1
digitalWrite(B2_PIN, LOW); // Apaga B2
digitalWrite(EV2_PIN, LOW); // EV2 en disipador
digitalWrite(AERO_PIN, LOW); // Apaga aerotermia

// Apagar EV de zonas mientras se atiende la demanda de ACS
digitalWrite(EV3_PIN, LOW); // Apaga EV3
digitalWrite(EV4_PIN, LOW); // Apaga EV4
digitalWrite(EV5_PIN, LOW); // Apaga EV5
} else {
// T2=ON, T1=OFF, Demanda simultánea con aerotermia
digitalWrite(AERO_PIN, HIGH); // Activa aerotermia
digitalWrite(EV1_PIN, HIGH); // EV1 hacia ACS
digitalWrite(B1_PIN, LOW); // Apaga B1
digitalWrite(B2_PIN, LOW); // Apaga B2
digitalWrite(EV2_PIN, LOW); // EV2 en disipador

// Apagar EV de zonas mientras se atiende la demanda de ACS
digitalWrite(EV3_PIN, LOW); // Apaga EV3
digitalWrite(EV4_PIN, LOW); // Apaga EV4
digitalWrite(EV5_PIN, LOW); // Apaga EV5
}
}

// Verificación constante: si T4, T5 o T6 están apagados, las EV correspondientes se apagan (repetido por seguridad)
if (!T4) digitalWrite(EV3_PIN, LOW); // Apaga EV3 si T4 está apagado
if (!T5) digitalWrite(EV4_PIN, LOW); // Apaga EV4 si T5 está apagado
if (!T6) digitalWrite(EV5_PIN, LOW); // Apaga EV5 si T6 está apagado
}

Aquí está si alguien necesita leerlo.

Muchas gracias a mi me lo ponia todo descolocado asi esta mejor :joy:

ChatGPT eliminó los números de línea para que no perdiera toda la noche. Espero que no haya cambiado nada más, pero no tengo tiempo de verificar todo para asegurarme.

En unas horas lo posteo yo otra vez de todas formas desde el pc que ahora el movil no me deja, aunque esta completo de todo la verdad creo que lo se ha dejado nada

1 Like

Primer problema que veo: Los relés que activan las entradas son de 220VAC y su bobina no está protegida con un varistor o snubber, con lo que al activarse y desactivarse produce un ruido importante que va a parar a la alimentación de Arduino. Toda bobina ha de estar protegida.

Segundo problema: ¿código chapGPT? ¿de verdad? Bueno, no me extraña. Los contactos del relé te van a producir muchos disparos falsos. Un contacto no se cierra/abre muy rápido, además de que produce unos rebotes que el Arduino al ser más rápido reconoce. En este tutorial Como NO leer un botón y como SI debemos hacerlo lo expliqué. Aunque el tutorial se aplica a pulsadores, ocurre lo mismo con interruptores, conmutadores, contactos de relé, etc. Tu código ni siquiera tiene delay (bravo!) con lo cual, al activar una entrada cualquiera hará cosas no deseadas.

De todas formas por lo que veo en tu esquema estas utilizando +5V para la entrada del pin, con lo cual además tienes la entrada de arduino en "flotación", es decir, sin un voltaje fijo, con lo cual también va a interpretar las entradas con cualquier valor. Si usas +5V deberías colocar una resistencia a negativo desde el pin de entrada, lo que se conoce como "pull-down". Quizás sea más práctico llevar una configuración donde llevas el pin al interruptor y de este a GND, así puedes aprovechar la resistencia pull-up interna del arduino.

Luego otro defecto es que esa placa de relés funciona al revés, es decir, si haces:

digitalWrite(pinRele, LOW);

En realidad estas activando el relé y no apagándolo, con lo cual otro efecto no deseado en el código.

La fuente no me gusta mucho, es muy simple, posiblemente tenga mucho rizado y cuando se activa algún rele meta alteraciones en el voltaje. Al menos le colocaría un condensador extra de 2200uF a la salida.

De momento todo lo que puedo decir, si tengo otro rato aprovecharé para darte algunas recomendaciones.

1 Like

Muchas cosas para objetar
Como básicamente no me gustaba por la cantidad de fallos que ví lo hice de nuevo.
Agregué algo que me muestre en que estado esta cada cosa y si hay cambios en los reles.
También cambié toda tu terminología, no es adecuada salvo para un PLC pero esto no es un PLC es un microcontrolador, asi que basado en tus comentarios use etiquetas tipo CamelCase

// Definimos los pines para los termostatos
#define ChimeneaPin 2       // Chimenea
#define ACSPin 3            // ACS (ON/OFF)
#define InerciaPin 4        // Inercia (ON/OFF)
#define SueloRadiantePin 5  // Suelo radiante
#define Planta1Pin 6        // Planta 1º
#define Planta2Pin 7        // Planta 2º

// Definimos los pines para las electroválvulas y bombas
#define EVACSPin 8          // ACS-Inercia
#define EVCalefaccionPin 9  // Calefacción-Disipador
#define EVSueloRadiantePin 10 // Zona suelo radiante
#define EVPlanta1Pin 11     // Zona planta 1º
#define EVPlanta2Pin 12     // Zona planta 2º
#define BombaPrimariaPin 13 // Bomba circuito Primario
#define BombaSecundariaPin A0 // Bomba circuito Secundario
#define AerotermiaPin A1    // Contacto para Aerotermia

// Variables para guardar los estados anteriores
bool estadoPrevioChimenea, estadoPrevioACS, estadoPrevioInercia;
bool estadoPrevioSueloRadiante, estadoPrevioPlanta1, estadoPrevioPlanta2;

void setup() {
  Serial.begin(9600);

  // Configuración de pines como entrada
  pinMode(ChimeneaPin, INPUT);
  pinMode(ACSPin, INPUT);
  pinMode(InerciaPin, INPUT);
  pinMode(SueloRadiantePin, INPUT);
  pinMode(Planta1Pin, INPUT);
  pinMode(Planta2Pin, INPUT);

  // Configuración de pines como salida
  pinMode(EVACSPin, OUTPUT);
  pinMode(EVCalefaccionPin, OUTPUT);
  pinMode(EVSueloRadiantePin, OUTPUT);
  pinMode(EVPlanta1Pin, OUTPUT);
  pinMode(EVPlanta2Pin, OUTPUT);
  pinMode(BombaPrimariaPin, OUTPUT);
  pinMode(BombaSecundariaPin, OUTPUT);
  pinMode(AerotermiaPin, OUTPUT);

  // Inicializamos todo en apagado
  digitalWrite(EVACSPin, LOW);
  digitalWrite(EVCalefaccionPin, LOW);
  digitalWrite(EVSueloRadiantePin, LOW);
  digitalWrite(EVPlanta1Pin, LOW);
  digitalWrite(EVPlanta2Pin, LOW);
  digitalWrite(BombaPrimariaPin, LOW);
  digitalWrite(BombaSecundariaPin, LOW);
  digitalWrite(AerotermiaPin, LOW);
}

void loop() {
  // Leemos los estados de los termostatos
  bool estadoChimenea = digitalRead(ChimeneaPin);
  bool estadoACS = digitalRead(ACSPin);
  bool estadoInercia = digitalRead(InerciaPin);
  bool estadoSueloRadiante = digitalRead(SueloRadiantePin);
  bool estadoPlanta1 = digitalRead(Planta1Pin);
  bool estadoPlanta2 = digitalRead(Planta2Pin);

  // Verificamos si hubo algún cambio de estado
  if (estadoChimenea != estadoPrevioChimenea) {
    Serial.print("Chimenea: ");
    Serial.println(estadoChimenea ? "ON" : "OFF");
    estadoPrevioChimenea = estadoChimenea;
  }

  if (estadoACS != estadoPrevioACS) {
    Serial.print("ACS: ");
    Serial.println(estadoACS ? "ON" : "OFF");
    estadoPrevioACS = estadoACS;
  }

  if (estadoInercia != estadoPrevioInercia) {
    Serial.print("Inercia: ");
    Serial.println(estadoInercia ? "ON" : "OFF");
    estadoPrevioInercia = estadoInercia;
  }

  if (estadoSueloRadiante != estadoPrevioSueloRadiante) {
    Serial.print("Suelo radiante: ");
    Serial.println(estadoSueloRadiante ? "ON" : "OFF");
    estadoPrevioSueloRadiante = estadoSueloRadiante;
  }

  if (estadoPlanta1 != estadoPrevioPlanta1) {
    Serial.print("Planta 1º: ");
    Serial.println(estadoPlanta1 ? "ON" : "OFF");
    estadoPrevioPlanta1 = estadoPlanta1;
  }

  if (estadoPlanta2 != estadoPrevioPlanta2) {
    Serial.print("Planta 2º: ");
    Serial.println(estadoPlanta2 ? "ON" : "OFF");
    estadoPrevioPlanta2 = estadoPlanta2;
  }

  // Lógica de control:

  // Sin demanda de ACS ni calefacción: todo apagado
  if (!estadoACS && !(estadoSueloRadiante || estadoPlanta1 || estadoPlanta2)) {
    if (estadoChimenea) {
      // Chimenea encendida, todo en temperatura
      digitalWrite(EVACSPin, LOW); // EV1 hacia inercia
      digitalWrite(EVCalefaccionPin, LOW); // EV2 hacia disipador
      digitalWrite(BombaPrimariaPin, HIGH); // Enciende B1
      digitalWrite(BombaSecundariaPin, HIGH); // Enciende B2
    } else {
      // Sin demanda de calor
      digitalWrite(EVACSPin, LOW); // EV1 en inercia
      digitalWrite(EVCalefaccionPin, LOW); // EV2 en disipador
      digitalWrite(BombaPrimariaPin, LOW); // Apaga B1
      digitalWrite(BombaSecundariaPin, LOW); // Apaga B2
      digitalWrite(AerotermiaPin, LOW); // Apaga aerotermia
    }
  }

  // Demanda de ACS sin calefacción
  if (estadoACS && !(estadoSueloRadiante || estadoPlanta1 || estadoPlanta2)) {
    if (estadoChimenea) {
      // ACS demandado
      digitalWrite(EVACSPin, HIGH); // EV1 hacia ACS
      digitalWrite(BombaPrimariaPin, HIGH); // Enciende B1
      digitalWrite(BombaSecundariaPin, LOW); // Apaga B2
      digitalWrite(EVCalefaccionPin, LOW); // EV2 en disipador
      digitalWrite(AerotermiaPin, LOW); // Apaga aerotermia
    } else {
      // ACS demandado pero sin chimenea
      digitalWrite(AerotermiaPin, HIGH); // Activa aerotermia
      digitalWrite(EVACSPin, HIGH); // EV1 hacia ACS
      digitalWrite(BombaPrimariaPin, LOW); // Apaga B1
      digitalWrite(BombaSecundariaPin, LOW); // Apaga B2
      digitalWrite(EVCalefaccionPin, LOW); // EV2 en disipador
    }
  }

  // Demanda de calefacción sin ACS
  if (!estadoACS && (estadoSueloRadiante || estadoPlanta1 || estadoPlanta2)) {
    if (estadoChimenea) {
      // Calefacción demandada
      digitalWrite(EVACSPin, LOW); // EV1 hacia inercia
      digitalWrite(EVCalefaccionPin, HIGH); // EV2 hacia calefacción
      digitalWrite(BombaPrimariaPin, HIGH); // Enciende B1
      digitalWrite(BombaSecundariaPin, HIGH); // Enciende B2
      digitalWrite(EVSueloRadiantePin, estadoSueloRadiante); // EV3 según T4
      digitalWrite(EVPlanta1Pin, estadoPlanta1); // EV4 según T5
      digitalWrite(EVPlanta2Pin, estadoPlanta2); // EV5 según T6
      digitalWrite(AerotermiaPin, LOW); // Apaga aerotermia
    } else {
      // Calefacción con aerotermia
      digitalWrite(AerotermiaPin, HIGH); // Activa aerotermia
      digitalWrite(EVACSPin, LOW); // EV1 hacia inercia
      digitalWrite(EVCalefaccionPin, HIGH); // EV2 hacia calefacción
      digitalWrite(BombaPrimariaPin, LOW); // Apaga B1
      digitalWrite(BombaSecundariaPin, HIGH); // Enciende B2
      digitalWrite(EVSueloRadiantePin, estadoSueloRadiante); // EV3 según T4
      digitalWrite(EVPlanta1Pin, estadoPlanta1); // EV4 según T5
      digitalWrite(EVPlanta2Pin, estadoPlanta2); // EV5 según T6
    }
  }

  // Demanda de ACS y calefacción simultáneamente
  if (estadoACS && (estadoSueloRadiante || estadoPlanta1 || estadoPlanta2)) {
    if (estadoChimenea) {
      // Demanda simultánea de ACS y calefacción
      digitalWrite(EVACSPin, HIGH); // EV1 hacia ACS
      digitalWrite(BombaPrimariaPin, HIGH); // Enciende B1
      digitalWrite(BombaSecundariaPin, LOW); // Apaga B2
      digitalWrite(EVCalefaccionPin, LOW); // EV2 en disipador
      digitalWrite(AerotermiaPin, LOW); // Apaga aerotermia

      // Apagar EV de zonas mientras se atiende la demanda de ACS
      digitalWrite(EVSueloRadiantePin, LOW); // Apaga EV3
      digitalWrite(EVPlanta1Pin, LOW); // Apaga EV4
      digitalWrite(EVPlanta2Pin, LOW); // Apaga EV5
    } else {
      // Demanda simultánea con aerotermia
      digitalWrite(AerotermiaPin, HIGH); // Activa aerotermia
      digitalWrite(EVACSPin, HIGH); // EV1 hacia ACS
      digitalWrite(BombaPrimariaPin, LOW); // Apaga B1
      digitalWrite(BombaSecundariaPin, LOW); // Apaga B2
      digitalWrite(EVCalefaccionPin, LOW); // EV2 en disipador

      // Apagar EV de zonas mientras se atiende la demanda de ACS
      digitalWrite(EVSueloRadiantePin, LOW); // Apaga EV3
      digitalWrite(EVPlanta1Pin, LOW); // Apaga EV4
      digitalWrite(EVPlanta2Pin, LOW); // Apaga EV5
    }
  }
}

Ahora cuando presiono un pulsador se ve que todo cambia.
Lo primero que veo es que si usas relés estos rebotan, así que hay que agregar rutinas anti rebote o simplemente usara la librería Bounce2 que lo hace por nosotros.
Ahora lo hago pero solo para que veas como ha cambiado el código, dejo esto intermedio.

2 Likes

Muchas gracias veo interesantisimo todo eso que dices, son cosas que me suenan de verlas en tutoriales pero es verdad que no se han aplicado aqui.
Lo de la proteccion de las bobinas de los reles 220 no influye ya que el rateo se produce estando ellos conectados o no, hace lo mismo.
Pensaba que esto funcionaba como en automatismos industriales antiguos simplemente 1 o 0 pero ya veo que es mucho mas.

Bueno, y acá con Bounce2

#include <Bounce2.h>

// Definimos los pines para los termostatos
#define ChimeneaPin 2 // Chimenea
#define ACSPin 3 // ACS (ON/OFF)
#define InerciaPin 4 // Inercia (ON/OFF)
#define SueloRadiantePin 5 // Suelo radiante
#define Planta1Pin 6 // Planta 1º
#define Planta2Pin 7 // Planta 2º

// Definimos los pines para las electroválvulas y bombas
#define EV1Pin 8 // ACS-Inercia
#define EV2Pin 9 // Calefacción-Disipador
#define EV3Pin 10 // Zona suelo radiante
#define EV4Pin 11 // Zona planta 1º
#define EV5Pin 12 // Zona planta 2º
#define B1Pin 13 // Bomba circuito Primario
#define B2Pin A0 // Bomba circuito Secundario
#define AerotermiaPin A1 // Contacto para Aerotermia

// Tiempo de debounce
const int DEBOUNCE_TIME = 100;

// Objetos Bounce2 para los termostatos
Bounce bounceChimenea = Bounce();
Bounce bounceACS = Bounce();
Bounce bounceInercia = Bounce();
Bounce bounceSueloRadiante = Bounce();
Bounce bouncePlanta1 = Bounce();
Bounce bouncePlanta2 = Bounce();

void setup() {
  Serial.begin(9600);

  // Configuración de pines como entrada
  pinMode(ChimeneaPin, INPUT);
  pinMode(ACSPin, INPUT);
  pinMode(InerciaPin, INPUT);
  pinMode(SueloRadiantePin, INPUT);
  pinMode(Planta1Pin, INPUT);
  pinMode(Planta2Pin, INPUT);

  // Asignamos los pines a los objetos Bounce2 y configuramos el tiempo de debounce
  bounceChimenea.attach(ChimeneaPin);
  bounceChimenea.interval(DEBOUNCE_TIME);

  bounceACS.attach(ACSPin);
  bounceACS.interval(DEBOUNCE_TIME);

  bounceInercia.attach(InerciaPin);
  bounceInercia.interval(DEBOUNCE_TIME);

  bounceSueloRadiante.attach(SueloRadiantePin);
  bounceSueloRadiante.interval(DEBOUNCE_TIME);

  bouncePlanta1.attach(Planta1Pin);
  bouncePlanta1.interval(DEBOUNCE_TIME);

  bouncePlanta2.attach(Planta2Pin);
  bouncePlanta2.interval(DEBOUNCE_TIME);

  // Configuración de pines como salida
  pinMode(EV1Pin, OUTPUT);
  pinMode(EV2Pin, OUTPUT);
  pinMode(EV3Pin, OUTPUT);
  pinMode(EV4Pin, OUTPUT);
  pinMode(EV5Pin, OUTPUT);
  pinMode(B1Pin, OUTPUT);
  pinMode(B2Pin, OUTPUT);
  pinMode(AerotermiaPin, OUTPUT);

  // Inicializamos todo en apagado
  digitalWrite(EV1Pin, LOW);
  digitalWrite(EV2Pin, LOW);
  digitalWrite(EV3Pin, LOW);
  digitalWrite(EV4Pin, LOW);
  digitalWrite(EV5Pin, LOW);
  digitalWrite(B1Pin, LOW);
  digitalWrite(B2Pin, LOW);
  digitalWrite(AerotermiaPin, LOW);
}

void loop() {
  // Actualizamos los estados de los termostatos con debounce
  bounceChimenea.update();
  bounceACS.update();
  bounceInercia.update();
  bounceSueloRadiante.update();
  bouncePlanta1.update();
  bouncePlanta2.update();

  // Leemos los estados de los termostatos
  bool estadoChimenea = bounceChimenea.read();
  bool estadoACS = bounceACS.read();
  bool estadoInercia = bounceInercia.read();
  bool estadoSueloRadiante = bounceSueloRadiante.read();
  bool estadoPlanta1 = bouncePlanta1.read();
  bool estadoPlanta2 = bouncePlanta2.read();

  // Verificamos si hubo algún cambio de estado
  if (estadoChimenea != estadoPrevioChimenea) {
    Serial.print("Chimenea: ");
    Serial.println(estadoChimenea ? "ON" : "OFF");
    estadoPrevioChimenea = estadoChimenea;
  }

  if (estadoACS != estadoPrevioACS) {
    Serial.print("ACS: ");
    Serial.println(estadoACS ? "ON" : "OFF");
    estadoPrevioACS = estadoACS;
  }

  if (estadoInercia != estadoPrevioInercia) {
    Serial.print("Inercia: ");
    Serial.println(estadoInercia ? "ON" : "OFF");
    estadoPrevioInercia = estadoInercia;
  }

  if (estadoSueloRadiante != estadoPrevioSueloRadiante) {
    Serial.print("Suelo radiante: ");
    Serial.println(estadoSueloRadiante ? "ON" : "OFF");
    estadoPrevioSueloRadiante = estadoSueloRadiante;
  }

  if (estadoPlanta1 != estadoPrevioPlanta1) {
    Serial.print("Planta 1º: ");
    Serial.println(estadoPlanta1 ? "ON" : "OFF");
    estadoPrevioPlanta1 = estadoPlanta1;
  }

  if (estadoPlanta2 != estadoPrevioPlanta2) {
    Serial.print("Planta 2º: ");
    Serial.println(estadoPlanta2 ? "ON" : "OFF");
    estadoPrevioPlanta2 = estadoPlanta2;
  }

  // Lógica de control:

  // Sin demanda de ACS ni calefacción: todo apagado
  if (!estadoACS && !(estadoSueloRadiante || estadoPlanta1 || estadoPlanta2)) {
    if (estadoChimenea) {
      // Chimenea encendida, todo en temperatura
      digitalWrite(EVACSPin, LOW); // EV1 hacia inercia
      digitalWrite(EVCalefaccionPin, LOW); // EV2 hacia disipador
      digitalWrite(BombaPrimariaPin, HIGH); // Enciende B1
      digitalWrite(BombaSecundariaPin, HIGH); // Enciende B2
    } else {
      // Sin demanda de calor
      digitalWrite(EVACSPin, LOW); // EV1 en inercia
      digitalWrite(EVCalefaccionPin, LOW); // EV2 en disipador
      digitalWrite(BombaPrimariaPin, LOW); // Apaga B1
      digitalWrite(BombaSecundariaPin, LOW); // Apaga B2
      digitalWrite(AerotermiaPin, LOW); // Apaga aerotermia
    }
  }

  // Demanda de ACS sin calefacción
  if (estadoACS && !(estadoSueloRadiante || estadoPlanta1 || estadoPlanta2)) {
    if (estadoChimenea) {
      // ACS demandado
      digitalWrite(EVACSPin, HIGH); // EV1 hacia ACS
      digitalWrite(BombaPrimariaPin, HIGH); // Enciende B1
      digitalWrite(BombaSecundariaPin, LOW); // Apaga B2
      digitalWrite(EVCalefaccionPin, LOW); // EV2 en disipador
      digitalWrite(AerotermiaPin, LOW); // Apaga aerotermia
    } else {
      // ACS demandado pero sin chimenea
      digitalWrite(AerotermiaPin, HIGH); // Activa aerotermia
      digitalWrite(EVACSPin, HIGH); // EV1 hacia ACS
      digitalWrite(BombaPrimariaPin, LOW); // Apaga B1
      digitalWrite(BombaSecundariaPin, LOW); // Apaga B2
      digitalWrite(EVCalefaccionPin, LOW); // EV2 en disipador
    }
  }

  // Demanda de calefacción sin ACS
  if (!estadoACS && (estadoSueloRadiante || estadoPlanta1 || estadoPlanta2)) {
    if (estadoChimenea) {
      // Calefacción demandada
      digitalWrite(EVACSPin, LOW); // EV1 hacia inercia
      digitalWrite(EVCalefaccionPin, HIGH); // EV2 hacia calefacción
      digitalWrite(BombaPrimariaPin, HIGH); // Enciende B1
      digitalWrite(BombaSecundariaPin, HIGH); // Enciende B2
      digitalWrite(EVSueloRadiantePin, estadoSueloRadiante); // EV3 según T4
      digitalWrite(EVPlanta1Pin, estadoPlanta1); // EV4 según T5
      digitalWrite(EVPlanta2Pin, estadoPlanta2); // EV5 según T6
      digitalWrite(AerotermiaPin, LOW); // Apaga aerotermia
    } else {
      // Calefacción con aerotermia
      digitalWrite(AerotermiaPin, HIGH); // Activa aerotermia
      digitalWrite(EVACSPin, LOW); // EV1 hacia inercia
      digitalWrite(EVCalefaccionPin, HIGH); // EV2 hacia calefacción
      digitalWrite(BombaPrimariaPin, LOW); // Apaga B1
      digitalWrite(BombaSecundariaPin, HIGH); // Enciende B2
      digitalWrite(EVSueloRadiantePin, estadoSueloRadiante); // EV3 según T4
      digitalWrite(EVPlanta1Pin, estadoPlanta1); // EV4 según T5
      digitalWrite(EVPlanta2Pin, estadoPlanta2); // EV5 según T6
    }
  }

  // Demanda de ACS y calefacción simultáneamente
  if (estadoACS && (estadoSueloRadiante || estadoPlanta1 || estadoPlanta2)) {
    if (estadoChimenea) {
      // Demanda simultánea de ACS y calefacción
      digitalWrite(EVACSPin, HIGH); // EV1 hacia ACS
      digitalWrite(BombaPrimariaPin, HIGH); // Enciende B1
      digitalWrite(BombaSecundariaPin, LOW); // Apaga B2
      digitalWrite(EVCalefaccionPin, LOW); // EV2 en disipador
      digitalWrite(AerotermiaPin, LOW); // Apaga aerotermia

      // Apagar EV de zonas mientras se atiende la demanda de ACS
      digitalWrite(EVSueloRadiantePin, LOW); // Apaga EV3
      digitalWrite(EVPlanta1Pin, LOW); // Apaga EV4
      digitalWrite(EVPlanta2Pin, LOW); // Apaga EV5
    } else {
      // Demanda simultánea con aerotermia
      digitalWrite(AerotermiaPin, HIGH); // Activa aerotermia
      digitalWrite(EVACSPin, HIGH); // EV1 hacia ACS
      digitalWrite(BombaPrimariaPin, LOW); // Apaga B1
      digitalWrite(BombaSecundariaPin, LOW); // Apaga B2
      digitalWrite(EVCalefaccionPin, LOW); // EV2 en disipador

      // Apagar EV de zonas mientras se atiende la demanda de ACS
      digitalWrite(EVSueloRadiantePin, LOW); // Apaga EV3
      digitalWrite(EVPlanta1Pin, LOW); // Apaga EV4
      digitalWrite(EVPlanta2Pin, LOW); // Apaga EV5
    }
  }
}

No digo que este bien.
Solo agregue antirebotes, porque tienes rebotes en cada termostato asociado a un relé. El relé al accionarse rebota y eso te genera fallos en tu código. Mira en documentación el tutorial de @victorjam al respecto.
Ahora quedará enmascarado.
A ver si mejora el comportamiento y si no, lo verás tal vez en el reporte serial de cambios o te vuelvas loco con algo que este fallando pero al menos lo verás.

Hay algo que no he analizado aun y es esto

digitalWrite(EVPlanta1Pin, estadoPlanta1); // EV4 según T5

cito este como ejemplo, pero no se si esta bien que uses estadoPlanta1 como elemento de control del rele correspondiente. Mi instinto dice que no.

1 Like