Go Down

Topic: Temporizando luces con arduino y alarma, DUDA. (Read 6467 times) previous topic - next topic

tiozes

Apr 22, 2012, 03:09 pm Last Edit: Apr 30, 2012, 01:09 am by coleoptero Reason: 1
Buenas a todos, estoy armando una alamar para un chalet que tengo, ya tengo solucionado el funcionamiento de sensores, el armado y desarmado con su correspondiente cuenta atras y hasta hay todo bien.

Pero ahora tengo el problema a temporizar las luces, no se como tengo tengo que hacerlo para que salte a una determinada hora y decirle que tiempo tienen que estar encendidas, porque claro Delay no lo puedo usar porque si pongo 4 horas de estar las luces encendidas con Delay, pues estaria 4 Horas el programa parado alli.

Hay alguna otra manera de hacerlo sin usar Delay y millis? porque con este ultimo por mas que lo he intentado nunca me ha salido.ç


Saludos y gracias

PascuaL

Lo que te va a hacer la papeleta va a ser un RTC.

Sergegsx

necesitas un RTC 1307 para que el arduino sepa que hora es.

luego con millis tienes que hacer una comprobación de si tiene que actuar, tienes un ejemplo en el ide del arduino.
basicamente

if millis() - previousmillis > 300000 ....etc

esto dice que si han pasado 300 segundos desde que se declaro previousmillis con el valor millis, que entre en el if.
de esta forma el codigo para por esa linea y hasta que no se cumpla esa condición no entrara a hacer cosas.

saludos.

tiozes

Si, el reloj ya lo tengo funcionando, puesto en hora y mostrando en el LCD, lo que me daba miedo era usar millis jeje que ya lo intente y se resistió.

probare a hacer algo simple y luego ya lo complicare un poco mas.

Saludos y gracias.

Sergegsx

si has conseguido que funcione un RTC y un LCD veras que lo de millis es super sencillo. usa el ejemplo que viene con arduino...
en cuanto lo entiendas, lo usaras en muchos proyectos.

Code: [Select]

// constants won't change. Used here to
// set pin numbers:
const int ledPin =  13;      // the number of the LED pin

// Variables will change:
int ledState = LOW;             // ledState used to set the LED
long previousMillis = 0;        // will store last time LED was updated

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 1000;           // interval at which to blink (milliseconds)

void setup() {
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);     
}

void loop()
{
  // here is where you'd put code that needs to be running all the time.

  // check to see if it's time to blink the LED; that is, if the
  // difference between the current time and last time you blinked
  // the LED is bigger than the interval at which you want to
  // blink the LED.
  unsigned long currentMillis = millis();

  if(currentMillis - previousMillis > interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;   

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
}

tiozes

Code: [Select]
/* Parpadeo sin delay()
Enciende y apaga un LED conectado a un pin digital sin utilizar la función delay(). Esto significa que otro código se puede ejecutar al mismo tiempo sin ser interrumpido por el código que controla el parpadeo del LED
Circuito: Un LED conectado entre el pin 13 y el pin GND.
Nota: en muchos Arduinos hay un LED en la placa conectado al pin 13, por lo que no sería necesario un LED externo para este ejemplo.
Creado en 2005 por David A. Mellis, modificado el 8/2/2010 por Paul Stoffregen.
Este ejemplo es de dominio público*/

// las constantes no cambian. Las usamos aquí para establecer los números de los pines.
int ledPin = 13;   // el número del pin conectado al LED

//  variables que cambiarán de valor.
int ledState = LOW;   // ledState se usará para establecer el estado del LED

long previousMillis = 0;   // almacenará la última vez que el estado del LED
//se actualizó

// la siguiente variable es del tipo long por que el tiempo medido en
// milisegundos supera rápidamente al número que puede ser almacenado en una
// variable del tipo int
long interval = 1000;   // intervalo del parpadeo (en milisegundos)

void setup()
{
// establece el pin digital como salida:
pinMode(ledPin, OUTPUT);
}

void loop()
{
// Aquí es donde pondríamos el código que debe ejecutarse durante todo el
// tiempo.

// Se comprobará si es el momento de parpadear el LED, esto es, si la
// diferencia entre el tiempo transcurrido y el tiempo en que parpadeó
// por última vez el LED es mayor que el intervalo que establecimos en
// la declaración de variables.

unsigned long currentMillis = millis();    // Se toma el tiempo actual

// se comprueba si el tiempo actual menos el tiempo en que el LED cambió
// de estado por última vez es mayor que el intervalo.
if (currentMillis - previousMillis > interval){

// Si se cumple la condición se guarda el nuevo tiempo
// en el que el LED cambia de estado
previousMillis = currentMillis;

// Y ahora cambiamos de estado el LED, si está encendido a
// apagado o viceversa.
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;

// Hacemos que el contenido de la variable llegue al LED
digitalWrite(ledPin, ledState);
}
}


Buenas, encontre este codigo que es el mismo pero en castellano ejje porque de inglis ando un poco chungo jeje asi tambien para que la gente que este como yo lo entienda mejor.

Ya tengo mas o menos entendido bien como funciona, pero tengo una duda.
Como hago para para encender y apagar cosas a unas horas y unos dias de la semana especificos?
Porque asi como esta este ejemplo lo que hace es cuenta desde que inicia el programa y no usa el reloj en tiempo real.

Saludos

Imagina

Si tienes controlado el ejemplo del temporizador sin delay() y controlas el RTC (Reloj) ya es hora de que los mezcles, en vez de comparar millis() >= Ant_Millis tendrás que hacer una consulta al reloj, y compararla con la fecha y hora que quieres que se produzca el encendido y apagado de las luces.

tiozes

Podrias ponerme un pequeño ejemplo? porque se a lo que te refieres pero asi de primeras no soy capaz de meterle mano jejejej  :~

Saludos y gracias

tiozes

Buenas de nuevo, he encontrado como encienden y apagan luces sin usar millis, asi tambien me podria servir la temporizacion de luces verdad?

Code: [Select]
//Control de iluminacion
void Luces()
{
 
  // A las 10:00 empiezan a encenderse los led blancos y azules
  if (hour == 10 && minute ==1)
  {
    ledon();
    Lcdini();
    Serial.print("Comienza a salir el Solete      ");
    for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=1) { //EFECTO FADING EN LUZ LUNA LEDS
    analogWrite(Lazul, fadeValue); 
    analogWrite(Lblanco, fadeValue);     
    delay(1000); 
    }
    lcdoff();
    ledoff();
  }
     
 
  // A las 11:00 empieza 50% led alta potencia y apagamos los led de amanecer
 
  if (hour == 11 && minute ==1)
  {
  digitalWrite (Rele3, HIGH);
  digitalWrite (Lazul,LOW);
  digitalWrite (Lblanco,LOW);
  }
 
  //A las 11.15 se encienden 100% luces
  if (hour == 11 && minute >15)
  {
  digitalWrite (Rele3, HIGH);
  digitalWrite (Rele4, HIGH);
  digitalWrite (Lazul,LOW);
  digitalWrite (Lblanco,LOW);
  }
 
  // Desde 12:00 hasta 20:00 100% luces
  if (hour >= 12 && hour < 20 )
  {
  digitalWrite (Rele4, HIGH);
  digitalWrite (Rele3, HIGH);
  digitalWrite (Lazul,LOW);
  digitalWrite (Lblanco,LOW);
  }
 
   if (hour == 21 && minute < 50)
  {
  digitalWrite (Rele4, HIGH); 
  digitalWrite (Rele3, HIGH);
  digitalWrite (Lazul,LOW);
  digitalWrite (Lblanco,LOW);
  }
 
  // A las 21:50 50% luces
 
  if (hour == 21 && minute > 50)
  {
  digitalWrite (Rele4, HIGH); 
  digitalWrite (Rele3, LOW);
  digitalWrite (Lazul,LOW);
  digitalWrite (Lblanco,LOW);
  }
 
  // A las 22:15 solo leds anochecer
 
  if (hour == 22 && minute > 14 && minute <44)
  {
  digitalWrite (Lazul, HIGH);
  digitalWrite (Lblanco, HIGH);
  digitalWrite (Rele4, LOW);
 
  }
 
  // A las 22:30h comienza anochecer
 
  if (hour == 22 && minute >30 && anochecer == 0)
  {
    Lcdini();
    ledon();
    Serial.print("    Comienza    a ponerse el Sol");
    for(int fadeValue = 255 ; fadeValue >= 100; fadeValue -=1) {
    analogWrite(Lblanco, fadeValue);
    analogWrite(Lazul, fadeValue); 
    delay(1500);
    }
    lcdoff();
    ledoff();
    anochecer = 1;
  }
 
    // A las 22.45 se va apagando el blanco
   
    if (hour == 22 && minute > 45 && anochecer== 1)
   {
    Lcdini();
    ledon();
    Serial.print("    El Sol          se acuesta   ");
    for(int fadeValue = 100 ; fadeValue >= 0; fadeValue -=1) {
    analogWrite(Lblanco, fadeValue); 
    delay(1000);
    }
    for(int fadeValue = 100 ; fadeValue >= 50; fadeValue -=1) {
    analogWrite(Lazul, fadeValue); 
    delay(1000);
    }
    ledoff();
    lcdoff();
    anochecer = 2;
       
}
  // A las 23:10 se va apagando
 
  if (hour == 23 && minute  >10 && anochecer ==2)
   {
    Lcdini();
    ledon();
    Serial.print("La luna esconde   Buenas noches");
    for(int fadeValue = 50 ; fadeValue >= 0; fadeValue -=1) {
    analogWrite(Lazul, fadeValue); 
    p();
    }   
    ledoff();
    lcdoff();
    anochecer = 0;
   }
   
}
 


Esto es de un proyecto para automatizar un acuario, de todas formas sigo interesado tambien en usar bien millis ya que el saber no ocupa lugar.

Saludos

PascuaL

Así es como te dijimos desde el principio.

tiozes

Pues asi me aparece el siguente error:

_2sensores.cpp: In function 'void loop()':
_2sensores:116: error: 'hour' was not declared in this scope

y el codigo simpre para probar que use es este:

Code: [Select]
// Alarma Chalet
#include <Wire.h>                   // Libreria para I2C
#include <LiquidCrystal_I2C.h>      // Libreria para LCD
#define DS1307_I2C_ADDRESS 0x68     // Direccion bus Reloj

LiquidCrystal_I2C lcd(0x27,16,2);  // Direccion de bus pantalla

const int pir1 = 2;            // Pin de entrada señal Pir 1
const int pir2 = 4;            // Pin de entrada señal Pir 2
const int ledEstado = 13;      // Led en pin 13 salto Pir 1 y Pir 2
int estadoPir1 = 0;            // Estado de Pir 1 "0"
int estadoPir2 = 0;            // Estado de Pir 2 "0"

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()

{
  lcd.init();                  // Inicializacion LCD
  pinMode(ledEstado, OUTPUT);  // Funcion de salida LedEstado pin 13
  pinMode(pir1, INPUT);        // Funcion de entrada Pir 1 pin 2
  pinMode(pir2, INPUT);        // Funcion de entrada Pir 2 pin 4
 
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  Wire.begin();
 
 

  // la primera vez debemos poner en hora, active esta parte y luego vuelva a quitarla
  /*second = 00;
  minute = 33;
  hour = 15;
  dayOfWeek = 6;
  dayOfMonth = 11;
  month = 2;
  year = 12;
 
  setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year); */
   
 
}

void loop()
{
  if (hour == 11 && minute >15)
  {
  digitalWrite (LedEstado, HIGH);
 
 
   lcd.backlight();             // Iluminacion LCD
   lcd.setCursor(0,0);          // Seleccionamos posicion del cursor
   
 
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;

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

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

  delay(1000); //Pausa durante 1 segundo
 
 
 
  estadoPir1 = digitalRead(pir1);  // Leer estado Pir 1
  estadoPir2 = digitalRead(pir2);  // Leer estado Pir 2
 
  lcd.backlight();             // Iluminacion LCD
  lcd.setCursor(9,1);          // Seleccionamos posicion del cursor

  if (estadoPir1 == HIGH) {        // Si esta sl sensor Pir 1 activado activa led Pin 13
      //Pone led Estado pin 13 a nivel alto
  lcd.print("Pir 1");            // Aparece en pantalla Pir 1
 
  }

  else {                           // Si no se da las condiciones anteriores pone led Estado a nivel bajo
 
    lcd.setCursor(9,1);
       
     if (estadoPir2 == HIGH) {        // Si esta sl sensor Pir 2 activado activa led Pin 13
     lcd.print("Pir 2");            // Aparece en pantalla Pir 2
 

 
  }

  else {                           // Si no se da las condiciones anteriores pone led Estado a nivel bajo
 
    lcd.setCursor(9,1);
    lcd.print("OK   ");             // Aparece en pantalla OK
   


  }
     
}
}

tiozes

#11
Apr 27, 2012, 12:46 am Last Edit: Apr 27, 2012, 09:07 am by tiozes Reason: 1
Buenas de nuevo, he hecho este  simple codigo, pero no hace nada a la hora que le indico.

Cual puede ser el fallo?
Code: [Select]
// Alarma Chalet
#include <Wire.h>                   // Libreria para I2C
#include <LiquidCrystal_I2C.h>      // Libreria para LCD
#define DS1307_I2C_ADDRESS 0x68     // Direccion bus Reloj

LiquidCrystal_I2C lcd(0x27,16,2);  // Direccion de bus pantalla
int ledEstado = 13;      // Led en pin 13 salto Pir 1 y Pir 2


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()

{

 lcd.init();                  // Inicializacion LCD
 lcd.backlight();             // Iluminacion LCD

 pinMode(ledEstado, OUTPUT);  // Funcion de salida LedEstado pin 13
 

 Serial.begin(9600);          // Puerto serie configurado a 9600 baudios.
 
 byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
 Wire.begin();
 
 

 // la primera vez debemos poner en hora, active esta parte y luego vuelva a quitarla
 /*second = 00;
 minute = 33;
 hour = 15;
 dayOfWeek = 6;
 dayOfMonth = 11;
 month = 2;
 year = 12;
 
 setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year); */
 
 
}

void loop()
{
 
 byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;

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

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

 delay(1000); //Pausa durante 1 segundo
 
 
  //A las 12:40 se encienden 100% luces
 if (hour == 12 && minute == 40)
 {
 digitalWrite (ledEstado, HIGH);  
 
 }
 

}


Saludos

Edito: buenas, ya he conseguido que se enciendan y apaguen a la hora que yo quiero, pero lo que no consigo es que lo haga a distintos dias de la semana, haciendolo de la siguiente manera:


Code: [Select]
//A las 12:40 se encienden 100% luces
 if(dayOfMonth == 27 && hour == 12 && minute == 40)
 {
 digitalWrite (ledEstado, HIGH);  
 
 }

Imagina

#12
Apr 27, 2012, 09:18 am Last Edit: Apr 27, 2012, 09:21 am by Imagina Reason: 1
Según tu código sería algo así...


Code: [Select]

// Si es LUNES y son las 12:40 se encienden las luces
 if(dayOfWeek == 1 && hour == 12 && minute == 40)
 {
 digitalWrite (ledEstado, HIGH);  
 }


edit: Este código encendería las luces TODOS los lunes a las 12:40...

tiozes

Ayer probé así y quizas puse algo mal porque no se encendia.

Tambien intente asi:

Code: [Select]
// Desde 12:00 hasta 20:00
  if (hour >= 12 && hour < 20 )
  {
  digitalWrite (ledEstado, HIGH);
 
  }


Y no funciona porque asi me ahorro el tener que poner hora de encendido y hora de apagado independientes de esta manera:

Code: [Select]
//A las 12:40 se encienden 100% luces
  if(hour == 12 && minute == 40)
  {
  digitalWrite (ledEstado, HIGH); 
 
  }
// Apagado a las 14:15
if(hour == 14 && minute == 15)
  {
  digitalWrite (ledEstado, LOW); 
 
  }


Imagina

Lo enciendes, pero no lo apagas..

Code: [Select]

// Desde 12:00 hasta 20:00
  if (hour >= 12 && hour < 20 )
  {
  digitalWrite (ledEstado, HIGH);
  } else
  {
    digitalWrite (ledEstado, HIGH);
  }


Te falta el pedazo de codigo de "else" en adelante...

Go Up