Error al activar un rele para un sistema de riego

Hola a todos, espero me puedan ayudar con el error que estoy cometiendo, tengo una programación para un Arduino mega 2560, estoy creando un sistema de riego, estoy usando un modulo RTC y un modulo de 4 relés. El inconveniente es que cargo el programa y el relé se me activa automáticamente, entra al if, y según mis condiciones lo apaga. Pero debería ser totalmente al revés: cargar el programa y que se mantenga apagado, y luego al entrar al if se prenda. Ya intenté cambiar los HIGH y LOW pero sigue sin funcionar.

Adjunto el codigo:

//SISTEMA DE RIEGO AUTOMÁTICO - CARACOLERA
//Uso de arduino Mega, pantalla OLED, RTC y módulo de 4 reles. 

#include <SPI.h>
#include <Wire.h> 
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "RTClib.h"

// Para pantalla OLED
#define ANCHO 128
#define ALTO 64
#define OLED_RESET 4

Adafruit_SSD1306 oled(ANCHO, ALTO, &Wire, OLED_RESET);

//////////////////////SISTEMA DE RELOJ
//Para el Programa
int n_dia;
int r_dia;
int n_mes;
int t_mes;
int n_anno;
int d_anno;
int t_siglo=6;
int rr_dia;
//int RELE = 50;
// Modulo RTC
RTC_DS1307 RTC;

bool riego = true; // para el If que controlará el riego.
bool riego_fin = true;

#define RELE 50

void setup () {
 Wire.begin(); // Inicia el puerto I2C
 RTC.begin(); // Inicia la comunicaci¢n con el RTC
 RTC.adjust(DateTime(__DATE__, __TIME__)); // Establece la fecha y hora (Comentar una vez establecida la hora)
 //el anterior se usa solo en la configuracion inicial
 Serial.begin(9600); // Establece la velocidad de datos del puerto serie
 oled.begin(SSD1306_SWITCHCAPVCC, 0X3C);
 pinMode(RELE, OUTPUT);
 
}


void loop(){


//////////////////////INICIO SISTEMA DE RELOJ Y PANTALLA OLED

 DateTime now = RTC.now(); // Obtiene la fecha y hora del RTC

 Serial.print(now.year(), DEC); // Año
 Serial.print('/');
 Serial.print(now.month(), DEC); // Mes
 Serial.print('/');
 Serial.print(now.day(), DEC); // Dia
 Serial.print(' ');
 Serial.print(now.hour(), DEC); // Horas
 Serial.print(':');
 Serial.print(now.minute(), DEC); // Minutos
 Serial.print(':');
 Serial.print(now.second(), DEC); // Segundos


 oled.clearDisplay();
 oled.setTextColor(WHITE);
 oled.setTextSize(1);

 oled.setCursor(0,0); 
 oled.print("D:");
 oled.print(now.year(), DEC);
 oled.print("/");
 oled.print(now.month(), DEC);
 oled.print("/");
 oled.print(now.day(), DEC);
 oled.print(" ");
 oled.setCursor(0,9);
 oled.print("T: ");
 oled.print(now.hour(), DEC);
 oled.print(":");
 oled.print(now.minute(), DEC);
 oled.print(":");
 oled.print(now.second(), DEC);
 oled.setCursor(0,18);
 //delay(1000); // La informaci¢n se actualiza cada 1 seg.
 oled.display();
  
 n_anno=(now.year()-2000);
 d_anno=n_anno/4;
 n_dia=now.day();
 n_mes=now.month();

 switch (n_mes) {
    case 1:
      t_mes=0;
      break;
    case 2:
      t_mes=3;
      break;
    case 3:
      t_mes=3;
      break;
    case 4:
      t_mes=6;
      break;
    case 5:
      t_mes=1;
      break;
    case 6:
      t_mes=4;
      break;
    case 7:
      t_mes=6;
      break;
    case 8:
      t_mes=2;
      break;
    case 9:
      t_mes=5;
      break;
    case 10:
      t_mes=0;
      break;
    case 11:
      t_mes=3;
      break;
    case 12:
      t_mes=5;
      break;
    default: 
      t_mes=t_mes;
    break;
 }

 r_dia=n_dia+t_mes+n_anno+d_anno+t_siglo;
 r_dia = r_dia % 7;


   
 switch (r_dia) {
    case 1:
       oled.print("Lun");
        Serial.println(" Lun");
      break;
      case 2:
       oled.print("Mar");
       Serial.println(" Mar");
      break;
      case 3:
       oled.print("Mie");
       Serial.println(" Mie");
       oled.setCursor(0,26);
       oled.print(r_dia);
       Serial.println(r_dia);
      break;
      case 4:
       oled.print("Jue");
       Serial.println(" Jue");
       oled.setCursor(0,26);
       oled.print(r_dia);
      break;
      case 5:
       oled.print("Vie");
       Serial.println(" Vie");
      break;
      case 6:
       oled.print("Sab");
       Serial.println(" Sab");
      break;
      case 0:
       oled.print("Dom");
       Serial.println(" Dom");
      break;
      default: 
       oled.print("---");
       Serial.println(" ---");
      break;
      oled.display();
 }

 oled.display();

int Dato1(r_dia); // se almacena el valor de la variable r_dia en una nueva variable como numero entero

 ////////////////////// FINAL SISTEMA DE RELOJ

 ////////////////////// ACCIONAMIENTO DE RELÉ PARA ACTIVAR EL RIEGO

/// If para día y hora específica de riego.
if (Dato1==2 && now.hour()==12 && now.minute()==14){ //condicional de día y hora especfica para activar el riego 
  if (riego == true){
   digitalWrite(RELE, HIGH);
   oled.setCursor(0,26);
   Serial.println("Riego activado");
  oled.print("Riego activado");
  oled.display();
  riego=false; //desactiva la alarma
  }
}


if (Dato1==2 && now.hour()==12 && now.minute()==15){ //condicional de día y hora especfica para activar el riego 
  if (riego_fin == true){
   digitalWrite(RELE,LOW);
   oled.setCursor(0,30);
   Serial.println("Riego desactivado");
  oled.print("Riego desactivado");
  oled.display();
  riego_fin=false; //desactiva la alarma
  }
}
 delay(1000);
 
if (now.hour()==2 && now.minute()==00){
  riego=true;
  riego_fin=true;

}


  }

Te fijaste si el rele necesita un 1 o un 0 para su activación? normalmente se activan con un 0, primero confirma que el hardware asociado esta bien y que lógica tiene.

1 Like

Seguramente estas usando unos reles que se activan a nivel bajo, (pon un enlace para confirmarlo), si es asi , donde mandas un LOW manda un HIGH y viceversa. añade en el setup y lo primero de todo la declaracion del pin y escribe un HIGH en el.
Comprueba que el modulo de reles no lleva un jumper para cambiar el nivel de disparo te evitaria lo anterior.
Saludos.

1 Like

Les adjunto una foto del circuito, ya que no estoy muy seguro de cómo ver si el Hardware necesita otro tipo de conección.

pruebalo solo, sin arduino ni programacion, solo averigua tirandole un 1 o un 0 a la entrada de cada rele para que veas con cual estado logico se activan.

1 Like

Hice una prueba con un pequeño programa parecido y pues me di cuenta que si funciona, en ese programa se enciende con un LOW y se apaga con un HIGH, sin embargo, probé cambiar eso en código del sistema de riego y de igual forma tengo el problema.

int RELE=50;

void setup() {
  // put your setup code here, to run once:
pinMode (RELE, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:

 digitalWrite (RELE, LOW);
 delay (5000);
 digitalWrite (RELE, HIGH);
 delay (10000);
}

Que raro, con el codigo original e invirtiendo los niveles prueba en el pin 49.

1 Like

Lo único que deberías hacer es cambiar la activación y desactivación por LOW y HIGH respectivamente (o sea al contrario de como lo tienes ahora), como ya te han dicho.

Una duda, por que haces semejante código para calcular el día de la semana pudiendo hacer

r_dia = now.dayOfTheWeek();

y con una array, usando r_dia como indice,lo resuelves, por ej.

char daysOfWeek[7][4] = {"Dom","Lun","Mar","Mie","Jue","Vie","Sab"};

y luego donde lo muestras

oled.print(daysOfWeek[r_dia]);
Serial.println(daysOfWeek[r_dia]);

Saludos

1 Like

Aun cambiando en los IF el LOW por el HIGH y viceversa, sigo teniendo el mismo inconveniente, respecto a la otra acotación voy a intentar ver si puedo minimizar el código, muchas gracias.

Solo para confirmar...

¿En el display aparece "Riego activado" cuando lo desactiva y viceversa?

1 Like

Tienes un error y es raro que el compilador no haya "tirado la bronca"

int Dato1(r_dia); // se almacena el valor de la variable r_dia en una nueva variable como numero entero 

así estás definiendo una función Dato1

Debe ser

int Dato1 = r_dia; 

aunque a mi criterio no tiene sentido, puedes usar directamente r_dia

1 Like

Te actualizo: acabé de poner una carga AC y cambiar el orden del LOW y HIGH para ver el funcionamiento.

En este caso ya puse en el primer IF el LOW y en el segundo el HIGH.
al carga el programa lo que pasa es que se activa el relé y prende el foco... cuando llega al primer condicional que es el que debería prender el foco bajo mis condiciones de dia y hora, como ya está encendido, pues se mantiene encendido y aparece en la pantalla "riego activado". Cuando llega al siguiente If ahora si se apaga el foco y sale "riego desactivado" y la no vuelve a prender el foco. Es decir que ahora el problema ya solo radica en que empieza encendido el rele.

Respecto a esto, estuvo raro, porque sabía que debería poder usar directamente r_dia pero por algún motivo no me leía el condicional, y solo me leyó de la forma en la que lo puedes ver en el codigo.

Ok, pero está mal definida la variable (de hecho no está definida por eso dije que es raro que no haya saltado el error al compilar), debe ser

int Dato1 = r_dia; 

Saludos

1 Like

ya lo reviso, muchas gracias.

Quiero actualizarles que fue lo que hice que al parecer solucionó el problema pero no sé si es lo mejor:

Puse LOW en el primer IF y en el segundo HIGH y en el void setup () añadí un '' digitalWrite(RELE,HIGH) y pues con eso ya no inició encendido.
Creo que fue lo que @gonpezzi me propuso pero no lo entendí a la primera :sweat_smile:

No sé si sea la mejor solución, si conocen una mejor les agradezco mucho que me la mencionen y finalmente muchas gracias por su ayuda!! (aún no comprendo por qué es necesario la linea adiciónal del setup porque no debería iniciar encendido de primera mano) Seguiré receptando comentarios del código, muchas gracias.

Pero no dijiste que lo habías hecho y no te había funcionado?
Ay, ay...

Debes agregar la línea en setup() para que inicie desactivado porque por defecto el pin está en LOW entonces lo activa.

Revisa lo que te expliqué sobre Dato1.

Saludos

1 Like

Lo siento jajaja, listo listo muchas gracias por la ayuda, ahora lo reviso! :sweat_smile:

A mi no me gusta trabajar con reles que se activan a nivel bajo, si se estropea el arduino o reseteas, conectan, aunque brevemente en el reseteo la carga conectada a ellos y si se va el arduino tendras una inundacion seguramente.
Una solucion seria invertir la señal de entrada de los reles con un inversor facil de hacer:
inversor
Con esto y los LOW y HIGH originales no tendras problemas y sera mas seguro.
Y siemppre tienes la opcion de cambiar a Reles con activacion en alto.

https://es.aliexpress.com/item/1005003965988817.html

1 Like

Muchas gracias por la ayuda! :slight_smile: lo tomaré en cuenta