Arduino Forum

International => Español => Software => Topic started by: Jossema106 on Dec 26, 2012, 08:10 pm

Title: encender rele segun tiempo
Post by: Jossema106 on Dec 26, 2012, 08:10 pm
hola! Para mi proyecto necesito encender y mantener encendido un rele por el tiempo establecido y se me ocurre lo siguiente,
tiempo = 12;
if (hour == hora && minute == minute && second == segundo){     
                       
                 digitalWrite(relayPin, HIGH);
                 delay(tiempo);
                 Serial.println("encendio");
              }
            digitalWrite(relayPin, LOW);
            Serial.println("apago");

Como lo veis?
Gracias
Title: Re: encender rele segun tiempo
Post by: OoTzToO on Dec 26, 2012, 09:18 pm
Con eso debería funcionar.

El único problema que se me ocurre es que el arduino, una vez que se apague (o reinicie), pone a cero los contadores de tiempo, así que te hace falta una fuente fiable de energía o una placa con contador específica que incluya su propia pila (que las hay por ahí (http://arduinoshield.net/shields/arduino-ds1307-real-time-clock-shield)).

Además, el tiempo máximo que dura el contador de tiempo del arduino es de unos 50 días ;)

;P
Title: Re: encender rele segun tiempo
Post by: Jossema106 on Dec 26, 2012, 09:53 pm
Gracias!

Tengo un rtc que es de donde coge las horas.
No entiendo lo de los 50 dias.

Por otro lado tengo que manejar otro rele y seguramente coincidan en el tiempo, al utilizar delay deja el arduino en "pause"? Si es asi no me serviria ya que al enceder uno no podria encender el otro no?
Title: Re: encender rele segun tiempo
Post by: OoTzToO on Dec 27, 2012, 06:18 pm
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 ;)
Title: Re: encender rele segun tiempo
Post by: Jossema106 on Dec 27, 2012, 06:24 pm
pero entonces si suceden dos eventos a la vez? Es decir se enciendo el tele de la calefaccion y es hora de regar?
Funcionara?
Title: Re: encender rele segun tiempo
Post by: OoTzToO on Dec 27, 2012, 06:27 pm
Si se dan las condiciones de cada uno sí, sin problema.

Ojito con las limitaciones de entrada y salida de corriente de los pines
Title: Re: encender rele segun tiempo
Post by: Jossema106 on Dec 27, 2012, 06:29 pm
Estoy empezando con esto, explicame por favor
Title: Re: encender rele segun tiempo
Post by: OoTzToO on Dec 27, 2012, 06:37 pm
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".
Title: Re: encender rele segun tiempo
Post by: Jossema106 on Dec 27, 2012, 06:39 pm
ok, gracias!
Title: Re: encender rele segun tiempo
Post by: maxid on Dec 27, 2012, 07:06 pm
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
Title: Re: encender rele segun tiempo
Post by: Jossema106 on Dec 27, 2012, 07:08 pm
se apaga cuando salga del if no? una vez que haya pasado el tiempo?
Title: Re: encender rele segun tiempo
Post by: Jossema106 on Dec 27, 2012, 07:13 pm
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
Title: Re: encender rele segun tiempo
Post by: maxid on Dec 27, 2012, 07:19 pm
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.
Title: Re: encender rele segun tiempo
Post by: Jossema106 on Dec 27, 2012, 07:40 pm
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.

Code: [Select]

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
Title: Re: encender rele segun tiempo
Post by: maxid on Dec 27, 2012, 07:59 pm
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.
Title: Re: encender rele segun tiempo
Post by: Jossema106 on Dec 27, 2012, 08:39 pm
muy buena idea!!!

Gracias, ya os contare!
Title: Re: encender rele segun tiempo
Post by: karagos on Jan 05, 2013, 12:56 am
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
Title: Re: encender rele segun tiempo
Post by: Jossema106 on Jan 05, 2013, 11:17 am
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
Title: Re: encender rele segun tiempo
Post by: karagos on Jan 05, 2013, 03:31 pm
no entiendo lo del fallo 45. yo lo tengo asi y no hay problemas
Title: Re: encender rele segun tiempo
Post by: Jossema106 on Jan 05, 2013, 07:35 pm
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
Title: Re: encender rele segun tiempo
Post by: karagos on Jan 12, 2013, 01:24 am
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.
Quote
//
// 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 ;)
Title: Re: encender rele segun tiempo
Post by: Jossema106 on Jan 17, 2013, 08:24 am
Perdon por no contestar antes. Espero que se hayan solucionado.


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


Gracias