Terrário automatizado

Estimados amigos me he embarcado en este proyecto a parte de de ser aficionado al mundo de los reptiles, anfibios y demas, también me llama el mundillo arduino, y con mis 40 tacos me pongo a la labor de intentar aprender, leo por aquí, allá y me decido a empezar.
El tema parece sencillo:

1 lcd 20x40 I2C
1 RTC I2C DS3231
1 sensor DHT22
1modulo 4 relays(luz, calor, sistema lluvia, ventilador(no incluido por ahora)
1 arduino nano

dado que enchufando todo esto no se entienden, me decido por empezar código y con el comienzan los problemas
1º- según enciendo el arduino se encienden los relays de lluvia y luz, aunque no sea la hora

2º- ¿como le digo al Sr arduino que cada 2 horas(o las que le indique) encienda el relé de lluvia durante
30 segundos?
y esta ya seria la caña : smiley-confuse: aunque me conformo con las anteriores
como podria modificar los datos sin tener que poner el arduino en el pc

Ante todo disculparme por el código, quizás no esté lo bien ordenado que debería pero yo lo que sé es lo que ustedes me enseñais, leyendo y leyendo...
Gracias a todos.

#include <Time.h>
#include <TimeLib.h>
#include <RTClib.h>
#include <Wire.h>                          // libreria para comunicación I2c             /
#include <LiquidCrystal_I2C.h>             // libreria para LCD por protocolo I2c        /
#include <DHT.h>                           // libreria para sensor temp/hum

                       
//////////////////////////////////////////////////////////////////////////////////////////
//             definir variables


int sensor = 8;    //pin desde el sensor dht22
int calor = 11;    //define pin relé manta termica 
int luz = 12;      //define pin luz
int temp;          //indica que el término temp se asociará a la temperatura
int humedad;       //indica que el término humedad se asociará a la humedad
int lluvia = 13;    // define rele bomba lluvia
int fun= 10;          //pin ventilador
int minutos;
int segundos;
String minut();
int minuto;
String segund();
int segundo;

DHT dht22(sensor, DHT22); // asociamos la libreria con el sensor (nº de pin y tipo de sensor) y nombre al que se asocia dht22
LiquidCrystal_I2C lcd(0x27,20,4); // asociamos libreria del display y la llamamos lcd indicamos puerto de conexion y las filas y columnas del display   /
RTC_DS3231 RTC;

void setup() {
Wire.begin();      // inicia comunicación I2C  
RTC.begin();       //inicia reloj rtc
lcd.begin(20,4);   // inicia LCD
dht22.begin();     // inicia el sensor tem/hume
lcd.clear();       // borra la pantalla
lcd.backlight();

pinMode(calor, INPUT);
pinMode(luz, OUTPUT);
pinMode(lluvia, OUTPUT);
pinMode(fun, OUTPUT);

//////// barra de progreso inicializar da tiempo para que el sensor se estabilice//////
  
  lcd.setCursor(0,0);
  lcd.print("Inicializando...");
  for (int i = 0; i <= 20; i++) {
    lcd.setCursor(i, 1);
    lcd.write((byte)4);
    delay(250);  
  }
  delay(250);
  lcd.clear();
  delay(500);
        
if (RTC.lostPower()) {RTC.adjust(DateTime(F(__DATE__), F(__TIME__)));}             //ajuste reloj 

}

void loop() {

////////////////reloj//////////////////


DateTime now = RTC.now(); //obtiene datos del modulo RTCif (RTC.lostPower()) {
minutos=now.minute();
segundos=now.second();
String minut= String(minutos, DEC); // convertimos a string los minutos en decimal
minuto=minut.toInt(); // asignamos a un entero (minuto) el valor de un string(minut)

String segund= String(segundos, DEC); // Idem
segundo=segund.toInt(); // Idem
lcd.setCursor(12,3); // colocamos el cursor para escribir la hora
lcd.print(now.hour(), DEC); // escribimos la hora
lcd.print(':');

if(minuto<10){ // comprobamos que sea un digito para añadir un 0
  lcd.print('0');
  }
lcd.print(minutos, DEC); // escribimos los minutos
lcd.print(':');

if(segundo<10){ // comprobamos que sea un digito para añadir un 0
  lcd.print('0');
  }
lcd.print(segundos, DEC); // escribimos los segundos  
 

 //////////sensor dht22 ///////////////
humedad = dht22.readHumidity();
temp = dht22.readTemperature();

///////////////////////////////función temperatura/////////////////////////////////////////////////

lcd.setCursor(0,0);
lcd.print("Temperatura: ");
lcd.print(temp);
lcd.print((char)223); 
       //símbolo de gradosº
if (temp<=20){   //enciende resistencia
               digitalWrite(calor, LOW);
               lcd.print(" ON ");
              
               }
      else{
               digitalWrite(calor, HIGH);
              lcd.print(" OFF ");
               
               }
if (temp>=20){   //enciende ventilador
                
               digitalWrite(fun, LOW);
            
              
               }
      else{
               digitalWrite(fun, HIGH);
            
               
               }
               
               
lcd.setCursor(0,1);
lcd.print("Humedad:     ");
lcd.print(humedad);
lcd.print("%");

///////////////////////////////función iluminación/////////////////////////////////////////////////

lcd.setCursor (0,2);
lcd.print("luz:     ");

    if(now.hour() == 12 && now.minute() == 00){        // hora de encendido de luces
      digitalWrite(luz,LOW);
      lcd.print("ON");
      
      
    }
    else if(now.hour() == 12 && now.minute() == 30){     // hora de apagado luces
      digitalWrite(luz,HIGH);
      lcd.print("OFF");
     
     
    }
///////////////////////////////función de lluvia/////////////////////////////////////////////////// 
   
lcd.setCursor (0,3);
lcd.print("Lluvia: ");


if(now.hour() == 13 && now.minute ()== 54&& now.second ()> 31){ 
    digitalWrite(lluvia, LOW);
    lcd.print("ON");
   delay(30000);                                          // 30 segundos
   digitalWrite(lluvia, HIGH);
  
   }
}

Por cierto subiré el código cuando ya esté funcionando al 100% para que el que lo quiera haga uso de él
ya se que somos muchos los que lo queremos, no contaba con esto jejejeje
el que adjunto aquí falta pulirlo

terrario.ino (3.7 KB)

Hola que tal de hecho tu función lluvia en realidad no es una función, solo es un fragmento de código, hay algo que no entendi, tu codigo funciona si o no?
Y como sabes que tu reloj esta bien sincronizado?
en eso de cada dos horas encender la lluvia no es nada dificil solo leer la hora y comprar la con una constante o varias, puedes usar la función millis() para hacer el conteo de las 30 segundos(30mil milisegundos);
Saludos.

no entiendo bien la primera pregunta, se supone que el tiempo ya me lo esta dando el rtc

respecto al uso del delay, o mal uso del delay, no es mas que fruto de la inexperiencia,
soy de los que leo y leo, y leo pero reconozco que esto me queda grande.

El código funciona por partes, por ejemplo, cuando no llega a 20 grados el relay se activa y enciende el cable de la resistencia y si se pasa enciende un pequeño ventilador.
despues. En la iluminación cuando le marcas una hora tambien funciona, pero cuando arranca el arduino se conecta en modo ON así como la lluvia.

Me comentaron que mi rele es de lógica inversa pero, si fuera de lógica inversa lo sería también para la temperatura creo yo

La barra de inicio fue un corta pega como algunas otras cosas, de hay tantos for y delays que seguramente se podrían ahorrar, tengo que seguir estudiando el tema y con vuestra ayuda ir puliendo
Sobretodo gracias por contestar.

breogan08:
Estimados amigos me he embarcado en este proyecto a parte de de ser aficionado al mundo de los reptiles, anfibios y demas, también me llama el mundillo arduino, y con mis 40 tacos me pongo a la labor de intentar aprender, leo por aquí, allá y me decido a empezar.
El tema parece sencillo:

1 lcd 20x40 I2C
1 RTC I2C DS3231
1 sensor DHT22
1modulo 4 relays(luz, calor, sistema lluvia, ventilador(no incluido por ahora)
1 arduino nano

El tema es cualquier cosa menos "sencillo"

Antes de dar ningún consejo: ¿qué conocimientos tienes de programación (empezaremos por ahí)?

Saludos

muy bajo: :confused: :confused: :confused: :confused:

Bueno mi consejo es que aprendas a usar arduino y luego retomes el proyecto, no al revés.

El proyecto seguirá ahi pero si no sabes como programar no podrás hacer nada y todo tendras que preguntarlo.

Primer paso ve a Documentación => Indice de temas tutoriales => Clases de Youtube:

Clases de Arduino GRATIS desde 0 hechas por mi (Clases desde la 1 a la 7)
Clases de Arduino GRATIS desde 0 hechas por mi (Clases desde la 8 en adelante
Tutoriales: Arduino desde cero

Comienza por ahi. Y luego te recomendaremos un buen libro.
Entre las clases varias tareas que quieres realizar son explicadas desde 0.
Verás que eso te pondrá en camino y te dará herramientas para poder juntar códigos y avanzar en tu proyecto.

Es solo una pausa para juntar conocimiento y luego verás como avanzas!!

Te agradezco los consejos que me das y de buen seguro que miraré los videotutoriales.
Entiendo lo del delay, sé que si lo usas, el arduino se paraliza en función del tiempo que le has puesto.

lo comprobé precisamente con la función del reloj en el lcd, cuando había un delay se paraba aunque no perdía la hora.

he ido puliendo o por lo menos limpiando el código y quitando la función de "lluvia" (que aun no se como hacerla)

Pero sigo con el problema de los relés. Ya he realizado otros proyectos con relés en cursos y prácticas de otros tutoriales y no he tenido problemas

realmente si que creo que sé cual es el problema pero nó la solución.
me explico:

hora de encendido 12:00 y apagado 13:00

a las 11:00 el relé "luz" parte como encendido al iniciar el arduino,por que no sabe a las 13:00 del dia anterior se supone que la orden era de apagarse, por eso cuando llega a las 12:00 se activa la luz(que en el relé, no oímos el "clic" por que ya esta activado pero si se enciende el "ON" en el display) y cuando llega a las 13:00 se desactiva el relé, y a partir de ahí el ciclo ya funciona correctamente.

Vamos que tendría que dejarlo 24h.

creo eh!

/* CONTROLADOR TERRARIOS
COMPONENTES 
    Arduino nano
    Reloj ds3231
    Lcd i2c 1602 20x4
    Modulo de 4 reles para iluminacion y sistema lluvia
    Dht22 para medir humedad y temperatura 
*/
//---------------------------------------------------
// 1. Librerias
//---------------------------------------------------

#include <Time.h>
#include <TimeLib.h>
#include <RTClib.h>
#include <Wire.h>                          // libreria para comunicación I2c             /
#include <LiquidCrystal_I2C.h>             // libreria para LCD por protocolo I2c        /
#include <DHT.h>                           // libreria para sensor temp/hum

//----------------------------------------------------
// 2. Pines
//----------------------------------------------------                       
#define sensor  8    //pin desde el sensor dht22
#define calor  2    //define pin relé manta termica 
#define luz    3     //define pin luz
#define lluvia 4    // define rele bomba lluvia
#define fun    1    //pin ventilador

//----------------------------------------------------
// 3. Variables y Comandos
//----------------------------------------------------

int temp ;         //indica que el término temp se asociará a la temperatura
int  humedad;
int minutos;
int segundos;
String minut();
int minuto;
String segund();
int segundo;

//----------------------------------------------------
// 4. Objetos
//----------------------------------------------------
DHT dht22(sensor, DHT22); // asociamos la libreria con el sensor (nº de pin y tipo de sensor) y nombre al que se asocia dht22
LiquidCrystal_I2C lcd(0x27,20,4); // asociamos libreria del display y la llamamos lcd indicamos puerto de conexion y las filas y columnas del display   /
RTC_DS3231 RTC;

//====================================================
// SETUP
//====================================================

void setup() {
//----------------------------------------------------
//  Pines
//----------------------------------------------------
pinMode(calor, OUTPUT);
pinMode(luz, OUTPUT);
pinMode(lluvia, OUTPUT);
pinMode(fun, OUTPUT);

//----------------------------------------------------
//  Objetos
//----------------------------------------------------
Serial.begin(9600); // abre el puerto Serie, configura los datos a 9600 bps  
Wire.begin();      // inicia comunicación I2C  
RTC.begin();       //inicia reloj rtc
lcd.begin(20,4);   // inicia LCD
dht22.begin();     // inicia el sensor tem/hume
lcd.clear();       // borra la pantalla
lcd.backlight();   //encender la retroiluminacion. NO QUISIERA que estubiera siempre encendida
// si botonera solo 30seg+- y apagarse



//////// barra de progreso inicializar da tiempo para que el sensor se estabilice////// 
//se ve rara  
  lcd.setCursor(0,0);
  lcd.print("Inicializando...");
  for (int i = 0; i <= 19; i++) {
    lcd.setCursor(i, 1);
    lcd.write((byte)4);
    delay(250);  
  }
  delay(250);
  lcd.clear();
  delay(500);
        
if (RTC.lostPower()) {RTC.adjust(DateTime(F(__DATE__), F(__TIME__)));}             //ajuste reloj 

}

void loop() {

  
////////////////reloj////////////////// sin problemas


DateTime now = RTC.now(); //obtiene datos del modulo RTCif (RTC.lostPower()) {
minutos=now.minute();
segundos=now.second();
String minut= String(minutos, DEC); // convertimos a string los minutos en decimal
minuto=minut.toInt(); // asignamos a un entero (minuto) el valor de un string(minut)

String segund= String(segundos, DEC); // Idem
segundo=segund.toInt(); // Idem
lcd.setCursor(12,3); // colocamos el cursor para escribir la hora
lcd.print(now.hour(), DEC); // escribimos la hora
lcd.print(':');

if(minuto<10){ // comprobamos que sea un digito para añadir un 0
  lcd.print('0');
  }
lcd.print(minutos, DEC); // escribimos los minutos
lcd.print(':');

if(segundo<10){ // comprobamos que sea un digito para añadir un 0
  lcd.print('0');
  }
lcd.print(segundos, DEC); // escribimos los segundos  
 

 //////////sensor dht22 ///////////////
 
humedad = dht22.readHumidity();
temp = dht22.readTemperature();

///////////////////////////////función temperatura/////////////////////////////////////////////////

lcd.setCursor(0,0);
lcd.print("Temperatura: ");
lcd.print(temp);
lcd.print((char)223);

//enciende resistencia, en principio funciona bien 
if (temp<=20){                                
               digitalWrite(calor, LOW);
               lcd.print(" ON ");
              
               }
      else{
               digitalWrite(calor, HIGH);
              lcd.print(" OFF ");
               
               }
//enciende ventilador, funciona bien  
 if (temp>=23){  
               digitalWrite(fun, LOW);
            
              
               }
      else{
               digitalWrite(fun, HIGH);
            
               
               }
               
             
lcd.setCursor(0,1);
lcd.print("Humedad:     ");
lcd.print(humedad);
lcd.print("%");

///////////////////////////////función iluminación/////////////////////////////////////////////////
// inicia en modo ON cuando no devería si no es la hora/////////////

lcd.setCursor (0,2);
lcd.print("luz:     ");

    if(now.hour() == 11 && now.minute() == 36){        // hora de encendido de luces
      digitalWrite(luz,LOW);
      lcd.print("ON");
      
      
    }
    else if(now.hour() == 11 && now.minute() == 39){     // hora de apagado luces
      digitalWrite(luz,HIGH);
      lcd.print("OFF");
     
     
    }
    
//función de lluvia enciende el relay 30 segundos,
//lo suyo sería cada dos horas o las horas que yo le indique, si nó, se quemaría la bomba o inundaría el terrario
//se inicia en modo ON y no se apaga

   
lcd.setCursor (0,3);
lcd.print("Lluvia: ");


/*if(now.hour() == 17 && now.minute ()== 48&& now.second ()> 31){ 
    digitalWrite(lluvia, LOW);
    lcd.print("ON ");
                                          // 30 segundos
   digitalWrite(lluvia, HIGH);
  
  
   }
*/   
}