encender rele segun tiempo

Lo de los 50 días tiene que ver con que usa 4bytes de memoria para el contador de tiempo (mira la función millis())

Efectivamente durante un delay se detiene la ejecución del programa, lo que puedes hacer es declarar un if() en el que compares el tiempo actual con el que tenías cuando activaste el relé, si es mayor que el tiempo preestablecido, lo apagas, sino, sigues a tus cosas :wink:

pero entonces si suceden dos eventos a la vez? Es decir se enciendo el tele de la calefaccion y es hora de regar?
Funcionara?

Si se dan las condiciones de cada uno sí, sin problema.

Ojito con las limitaciones de entrada y salida de corriente de los pines

Estoy empezando con esto, explicame por favor

En general, corrientes máximas de entrada o salida:

DC Current per I/O Pin ................................................ 40.0mA (por cada pin)
DC Current VCC and GND Pins................................. 200.0mA (alimentación)

Es decir, asegúrate (con la resistencia que pones antes del transistor) de que no sacas más de 40mA de cada pin al mismo tiempo (con sacar 15 o 20 mA te funciona igual) y en total de todos los pines también hay restricciones, unos 100 mA (dependiendo de qué pines sean)

Toda esta info viene en la datasheet del micro, en "electrical characteristics".

ok, gracias!

Nota de programador viejo: Si estas aprendiendo a programar no uses el estilo de los ejemplos es malisimo para seguir.

Esto esta mal, siempre se te va a apagar. El delay esta de mas ya que detiene por completo el resto de las tareas.
Puede usar una interupcion periodica y leer el reloj o cada 1,2,3.. segundos consultar el reloj y ver si ya es hora despues en el programa principal.
O algo mas simple.

long intervalo = 1000;

unsigned long currmillis = millis();

if(currmillis - prevmillis > intervalo) // si paso mas de 1 segundo leer el reloj
{
previousmillis = currmillis;

...llamar a la rutina de lectura del reloj.

if (hour == hora && minute == minute && second == segundo)
{
digitalWrite(relayPin, HIGH); //encender si estaba apagado
Serial.println("encendio");
}
else
{
digitalWrite(relayPin, LOW); //apagar si estaba prendido
Serial.println("apago");
}
}

... seguir con otras tareas

se apaga cuando salga del if no? una vez que haya pasado el tiempo?

He hecho la siguiente prueba,

Enciendo un led1 mientras que esta encendido (delay) doy la orden de encender led2, pero este no se enciende hasta que el delay ha terminado, por lo tanto no me sirve esta forma!

A ver si encontramos otra

relee mi respuesta, le di enviar sin querer.

Es asi el delay es un bucle con un nop, no hay ejecucion ni interruciones en ese momento. Ni funciona el puerto serial.

El problema de ese código, si no me equivoco ya que es muy parecido al ejemplo de blinkwithoutdelay, para adaptarlo al mio es que ahora mismo proboco el encendido del led pulsando un botón y el apagado es automático es decir que no se vuelve a pulsar el botón por lo tanto no entra en el if de comprobacion de estado, no se si me explico.

 if((ircode == 3108437760)){  //pulsado el boton del led1
    if (tiempo > 0){  
           digitalWrite(led, HIGH); 
           Serial.println("encendio");
           delay(tiempo);
           digitalWrite(led, LOW); 
           Serial.println("apagado");
           ircode = ir.read() ;
  }
   else 
     Serial.println("El tiempo de encendido es 0");
       
} 
if((ircode == 3091726080)){//pulsado el boton del led2
         digitalWrite(rojo, HIGH); 
         Serial.println("encendio rojo");
         delay(tiempo);
         digitalWrite(rojo, LOW); 
         Serial.println("apagado rojo");
         ircode = ir.read() ;
}

Si falta alguna llave es que he quitado de mas para dejar lo minimo posible.

Gracias de nuevo

Bueno eso es otra cosa.
Cuando entras a la rutina del boton 1 debes tomar la hora actual y guardarla, si presionas el boton 2 tambien lo guardas.
Despues consultas la hora cada tantos segundos como te mencione y revisas todas las variables (puede ser un array para mas facil manejo) guardadas mas el tiempo de encendido y si se cumplio lo pagas.
Separa el codigo en 2, te lo bosquejo

Rutinas de botones
..
.
.
.
Rutina de tiempos

incluso de esta forma si vuelves a presionar el boton extiendes el tiempo de encendido.

muy buena idea!!!

Gracias, ya os contare!

hola
que quieres controlar exactamente.
por que no utilizas las horas que te da el reloj.
es decir que se encienda a una hora y se apague a otra.
o que cuando pulses el boton compruebe la hora cada minuto y cuando llegue el momento (x minutos) se apague.
por ejemplo cuando sean las 5 empieza a mirar el reloj cada minuto y cuando sean las 10 se apaga (5+5)(hora que se enciende+mas lo que quieres que dure)
si quieres ser mas exacto utiliza minutos es decir las 13:30 son (13*60)+30 =810.

un saludo

Esa era la idea inicial pero por ahi hay un hilo fallo rtc creo q se llama, que describe el porque de buscar otra solucion ya que da siempre como valor 45, y no se cual ha sido el cambio a no ser que para el MEGA sea distinto y haya que levantar algun pin como pasa para la sd.

Sabes algo? Gracias

no entiendo lo del fallo 45. yo lo tengo asi y no hay problemas

Esto es lo que saca por pantalla
45:165:85 165/165/165 Day_of_week:165
45:165:85 165/165/165 Day_of_week:165
45:165:85 165/165/165 Day_of_week:165
45:165:85 165/165/165 Day_of_week:165

hola no llego a comprenderlo.
visita esta web. es mia, di de baja el dominio y se ha quedao pillada.
hay hay un ejemplo de un reloj.
te dejo un ejemplo. que muestra la hora por el serial de tu pc.

//
// CONTROLADOR ACUARIO V2.0

//FASE 1 - RELOJ

//////////////////////////////////////////////////////////////////////////7

#include <Wire.h> // Esta es la libreria de comunicacion I2C
#define DS1307_I2C_ADDRESS 0x68

// Convierte números normales decimales a BCD (binario decimal codificado)
byte decToBcd(byte val)
{
return ( (val/10*16) + (val%10) );
}

// Convierte BCD (binario decimal codificado) a números normales decimales
byte bcdToDec(byte val)
{
return ( (val/16*10) + (val%16) );
}

// 1) Sets the date and time on the ds1307
// 2) Starts the clock
// 3) Sets hour mode to 24 hour clock

void setDateDs1307(byte second, // 0-59
byte minute, // 0-59
byte hour, // 1-23
byte dayOfWeek, // 1-7
byte dayOfMonth, // 1-28/29/30/31
byte month, // 1-12
byte year) // 0-99
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0);
Wire.send(decToBcd(second));
Wire.send(decToBcd(minute));
Wire.send(decToBcd(hour));
Wire.send(decToBcd(dayOfWeek));
Wire.send(decToBcd(dayOfMonth));
Wire.send(decToBcd(month));
Wire.send(decToBcd(year));
Wire.endTransmission();
}

// Establece la fecha y la hora del reloj
void getDateDs1307(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
// Resetea el registro puntero
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0);
Wire.endTransmission();

Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

// Alguno de estos necesitan enmascarar porque ciertos bits son bits de control

*second = bcdToDec(Wire.receive() & 0x7f);
*minute = bcdToDec(Wire.receive());
*hour = bcdToDec(Wire.receive() & 0x3f);
*dayOfWeek = bcdToDec(Wire.receive());
*dayOfMonth = bcdToDec(Wire.receive());
*month = bcdToDec(Wire.receive());
*year = bcdToDec(Wire.receive());
}

void setup()
{
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
Wire.begin();
Serial.begin(9600);
Serial.print("serial inicializado");

// la primera vez debemos poner en hora, active esta parte y luego vuelva a quitarla
/*second = 00;
minute = 15;
hour = 21;
dayOfWeek = 6;
dayOfMonth = 19;
month = 9;
year = 9;

setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
*/}

void loop()
{
// Serial.print("hola mundo");
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;

getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);

Serial.print("20");
if (year < 10) Serial.print("0");
Serial.print(year, DEC);
Serial.print("/");
if (month < 10) Serial.print("0");
Serial.print(month, DEC);
Serial.print("/");
if (dayOfMonth < 10) Serial.print("0");
Serial.print(dayOfMonth, DEC);
Serial.print(" ");
if (hour < 10) Serial.print("0");
Serial.print(hour, DEC);
Serial.print(":");
if (minute < 10) Serial.print("0");
Serial.print(minute, DEC);
Serial.print(":");
if (second < 10) Serial.print("0");
Serial.print(second, DEC);
Serial.print(" Dia de la semana:");
Serial.println(dayOfWeek, DEC);
switch (dayOfWeek)
{
case 1:
Serial.println(" Lunes");
break;
case 2:
Serial.println(" Martes");
break;
case 3:
Serial.println(" Miercoles");
break;
case 4:
Serial.println(" Jueves");
break;
case 5:
Serial.println(" Viernes");
break;
case 6:
Serial.println(" Sabado");
break;
case 7:
Serial.println(" Domingo");
break;
}

delay(1000); //Pausa durante 1 segundo
}

carga esto y dime que te sale.
pd: no he conteatado antes por problemas familiares :wink:

Perdon por no contestar antes. Espero que se hayan solucionado.

Esta tarde si tengo tiempo, espero, lo cargo y te cuento

Gracias