Como cambiar delay() por millis o time? arduino

Todo cuanto tiene que ver con la obtención, almacenamiento y proceso de la información digital, sus aplicaciones y el software y hardware utilizado.
Mensaje
Autor
brunomars09
Mensajes: 9
Registrado: Sab Abr 29, 2017 3:21 am
País: España
Ciudad: Barcelona

Como cambiar delay() por millis o time? arduino

#1 Mensaje por brunomars09 »

Soy nuevo en el foro, estoy haciendo un proyecto pequeño con leds,sensores y servos, para simular una casa domotica el asunto es que e ido armando poco a poco un código para manejar todo, soy novato con el arduino y me pierdo aveces por el mismo desconocimiento. y
Todo esta manejado por Bluetooth mediante un app que cree en app inventor.

E estado armando mi proyecto poco a poco, primero fueron las luces, luego un sensor LDR, luego un sensor PIR, esta vez agregue un sensor de temperatura y humedad DTH11 y un ventilador, el cual se active automáticamente dependiendo de la temperatura, pero también poder encenderlo con la app del móvil. Si hay forma de mejorar el codigo, se agradeceria bastante. :|

Código: Seleccionar todo


#include <DHT.h>

int sensor = 22; 
int temp, humedad;

DHT dht (sensor, DHT11);

int led1 = 40;      //Luz 1 Comedor
int led2 = 41;      //Luz_2_Comedor
int led3 = 42;      //Luz_Cocina
int led4 = 43;      //Luz_1_Pasillo 
int led5 = 44;      //Luz_1_Pasillo 
int led6 = 45;      //Luz_Hab 1
int led7 = 46;      //Luz_Hab 1
int led8 = 47;      //Luz_Baño
int led9 = 48;      //Luz_Garaje
int led10 = 49;     //Luz_1_Jardin
int led11 = 50;     //Luz_2_Jardin
int led12 = 51;     //Luz_3_Jardin
int led13 = 52;     //Luz_4_Jardin

int ventilador= 8;

//bluetooth 
int estado = 0;

int LDRpin=A1;            // define el pin conectado al LDR
int LDRabc=0;
float LDRvoltaje=0;         // variable tipo flotante

int alarma=39;            //alarma contra intrusos y a la vez de incendios
int piralarma=7;         //sensor pir que detecta movimiento
int piralarmaState;       //variable para almacenar el valor del sensor pir


void setup(){
  
   
  Serial.begin(9600);
  dht.begin();
  pinMode(LDRpin, INPUT);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(led5, OUTPUT);
  pinMode(led6, OUTPUT);
  pinMode(led7, OUTPUT);
  pinMode(led8, OUTPUT);
  pinMode(led9, OUTPUT);
  pinMode(led10, OUTPUT);
  pinMode(led11, OUTPUT);
  pinMode(led12, OUTPUT);
  pinMode(led13, OUTPUT);

  pinMode(alarma, OUTPUT); 
  pinMode(piralarma, INPUT);


  pinMode(ventilador,OUTPUT);     //configuracion del ventilador


}
 
void loop(){  
 if( Serial.available()>0)   

   { estado = Serial.read();
  }
  
  if (estado=='s'){                 //si estado es igual a "6"  
    piralarmaState = digitalRead(piralarma);    //estado del pir alarma será igual al valor que lea del sensor

  if (piralarmaState==HIGH) {           //si hay intrusos
         digitalWrite(alarma, HIGH);           //activa alarma
         delay(500);
  if (estado=='t'){               //si estado es igual a "7"  
           digitalWrite(alarma, LOW);       //desactiva alarma
          }
        }
  }
  
  switch( estado)
  {
    case 'a':
    digitalWrite(led1, HIGH);    // primera luz del interior la casa 
    break;
    case 'b':
    digitalWrite(led1, LOW);
    break;
    
    case 'c':
    digitalWrite(led2, HIGH);
    break;
    case 'd':
    digitalWrite(led2, LOW);
    break;
    
    case 'e':
    digitalWrite(led3, HIGH);
    break;  
    case 'f':
    digitalWrite(led3, LOW);
    break;

    case 'g':
    digitalWrite(led4, HIGH);
    digitalWrite(led5, HIGH);        // luz pasillo ambas encienden a la vez 
    
    break;  
    case 'h':
    digitalWrite(led4, LOW);
    digitalWrite(led5, LOW);    // luz pasillo ambas se apagan a la vez 
    break;

    case 'i':
    digitalWrite(led6, HIGH);
    break;  
    case 'j':
    digitalWrite(led6, LOW);
    break;

    case 'k':
    digitalWrite(led7, HIGH);
    break;  
    case 'l':
    digitalWrite(led7, LOW);
    break;

    case 'm':
    digitalWrite(led8, HIGH);
    break;  
    case 'n':
    digitalWrite(led8, LOW);
    break;

    case 'o':
    digitalWrite(led9, HIGH);
    break;  
    case 'p':
    digitalWrite(led9, LOW);    // ultima luz del interior de la casa 
    break;

    case 'q':
    digitalWrite(led10, HIGH);
    digitalWrite(led11, HIGH);      // lucess del jardin  
    digitalWrite(led12, HIGH);
    digitalWrite(led13, HIGH);
    
    break;  
    case 'r':
    digitalWrite(led10, LOW);
    digitalWrite(led11, LOW);     //apagamos luces del jardin 
    digitalWrite(led12, LOW);
    digitalWrite(led13, LOW);
    break;

    case 't':
    digitalWrite(alarma, LOW);    // ultima luz del interior de la casa 
    break;
    
    case 'u':
    digitalWrite(ventilador, HIGH);
    break;
    case 'v':
    digitalWrite(ventilador, LOW);         // encendemos y apagamos ventilador
    break;


  }
  

  {
    LDRabc=analogRead(LDRpin);
    LDRvoltaje=LDRabc*(5.0/1023.0);
    Serial.print("voltaje LDR: ");
    delay(200);
    Serial.println(LDRvoltaje);
    
    if(LDRvoltaje<=1.20){
      digitalWrite(led10, HIGH);    
      delay(500);
      digitalWrite(led11, HIGH);      // luces del jardin encienden de noche
      delay(600);
      digitalWrite(led12, HIGH);
      delay(700);
      digitalWrite(led13, HIGH);
      delay(800);
  
      }

     else {
      
          digitalWrite(led10, LOW);
          digitalWrite(led11, LOW);   // luces del jardin se apagan de dia
          digitalWrite(led12, LOW);
          digitalWrite(led13, LOW);
          
          }
  }
  {
  humedad = dht.readHumidity();

  temp = dht.readTemperature();

  Serial.print("Temperatura:");
  Serial.print(temp);
  Serial.print("ºC Humedad: ");
  Serial.print(humedad);
  Serial.println("%");

  delay(500);

  if (temp < 27){                         // si la temp es menor de 27, el ventilador esta apagado
  digitalWrite(ventilador, LOW);
  }
else
  digitalWrite(ventilador,HIGH);   // ventilador activado
  
  }
   
    }

Logro que funcionen, lo malo que ahora tengo problemas con los delay , son muchos para un solo sketch y pues estube leyendo sobre millis() y los timer, que se pueden remplazar por el delay y permitir al procesador ejecutar las funciones correctamente, pero no tengo ni idea de como hacerlo. Debido a que hay muchos delay, los leds enciende con retraso y los últimos 4 encienden y se apagan repetitivamente al activarlos por el bluetooth. Si alguien me pude hechar un cable con esto estaria genial, Gracias de antemano.

Avatar de Usuario
mister_electronico
Mensajes: 122
Registrado: Mié Ene 15, 2014 8:44 pm
País: España
Ciudad: Asturias

Re: Como cambiar delay() por millis o time? arduino

#2 Mensaje por mister_electronico »

¿ Es un arduino atmega?

El problema no es por que haya muchos retardos, se pueden poner todos los retardos que uno quiera.

Al final del codigo resetea la variable "estado" por que si no te estara entrando continuamente en el estado if correspondiente y te estara haciendo perder un tiempo en ello.

Hay unos corchetes que no entiendo.

Justamente antes de la linea:

{ ----- no se por que abres este corchete.
LDRabc=analogRead(LDRpin);

que se cierra en:

digitalWrite(led13, LOW);

}
} ------ este es el que lo cierra y no encuentro el sentido.

inmendiatamente abres un corchete

{ ----- este corchete tampoco tiene ningun sentido.
humedad = dht.readHumidity();

Que se cierra en :

digitalWrite(ventilador,HIGH); // ventilador activado

} --- se cierra aqui.

Parece como comienzos de funciones a las que se te a olvidado poner el encabezamiento.

Para hacer todo mas legible te recomendaria el uso de funciones una para la temperatura, otra para el sensor de humedad, etc.. fuera del lazo de "loop".

Lo que te podria estar pasando es que cuando tu aprietas boton del movil activas el bluetooth y eso genera una interrupcion en el atmega y lee el nuevo dato, pero este dato no sera valido mientras no llegue a la rutina.

if( Serial.available()>0)

{ estado = Serial.read();
}

Despues de ejecutar esta interrupcion como no resteaste la variable "estado" volvera al punto donde se encontraba, entrara el if correspondiente ejecutara la orden antigua es por eso los los casos de indeterminacion.

Normalmente en los sensores tanto de temperatura, luz, humedad etc.. no puedess poner un poner un valor fijo de activacion esto es si por ejemplo la temperatura se activa mayor > 27 grados esto supone que se desactiva a a 27 grados y menor de 27, por lo cual cuando se encuentre en esa temperatura por poco error que se produce en la conversion analogica del arduino haciendo que este apagandose y entrando continuamente durante un tiempo.

Lo logico es que por ejemplo hagas un margen implementandole la funcion que a 27 grados se encienda y otra funcon que a 26 grados se apague.

Ten en cuenta que tambien la funcion:

if(LDRvoltaje<=1.20){

Te esta haciendo perder 2,6 segundos cada vez que entra en ella por la noche, no es necesario que pongas los retardos para que enciendas las luces.
Tambien puedes implentar una rutina que si la luces ya estan encendidas que no entre en la funcion.

Saludos.

brunomars09
Mensajes: 9
Registrado: Sab Abr 29, 2017 3:21 am
País: España
Ciudad: Barcelona

Re: Como cambiar delay() por millis o time? arduino

#3 Mensaje por brunomars09 »

mister_electronico escribió:¿ Es un arduino atmega?

El problema no es por que haya muchos retardos, se pueden poner todos los retardos que uno quiera.

Al final del codigo resetea la variable "estado" por que si no te estara entrando continuamente en el estado if correspondiente y te estara haciendo perder un tiempo en ello.

Hay unos corchetes que no entiendo.

Justamente antes de la linea:

{ ----- no se por que abres este corchete.
LDRabc=analogRead(LDRpin);

que se cierra en:

digitalWrite(led13, LOW);

}
} ------ este es el que lo cierra y no encuentro el sentido.

inmendiatamente abres un corchete

{ ----- este corchete tampoco tiene ningun sentido.
humedad = dht.readHumidity();

Que se cierra en :

digitalWrite(ventilador,HIGH); // ventilador activado

} --- se cierra aqui.

Parece como comienzos de funciones a las que se te a olvidado poner el encabezamiento.

Para hacer todo mas legible te recomendaria el uso de funciones una para la temperatura, otra para el sensor de humedad, etc.. fuera del lazo de "loop".

Lo que te podria estar pasando es que cuando tu aprietas boton del movil activas el bluetooth y eso genera una interrupcion en el atmega y lee el nuevo dato, pero este dato no sera valido mientras no llegue a la rutina.

if( Serial.available()>0)

{ estado = Serial.read();
}

Despues de ejecutar esta interrupcion como no resteaste la variable "estado" volvera al punto donde se encontraba, entrara el if correspondiente ejecutara la orden antigua es por eso los los casos de indeterminacion.

Normalmente en los sensores tanto de temperatura, luz, humedad etc.. no puedess poner un poner un valor fijo de activacion esto es si por ejemplo la temperatura se activa mayor > 27 grados esto supone que se desactiva a a 27 grados y menor de 27, por lo cual cuando se encuentre en esa temperatura por poco error que se produce en la conversion analogica del arduino haciendo que este apagandose y entrando continuamente durante un tiempo.

Lo logico es que por ejemplo hagas un margen implementandole la funcion que a 27 grados se encienda y otra funcon que a 26 grados se apague.

Ten en cuenta que tambien la funcion:

if(LDRvoltaje<=1.20){

Te esta haciendo perder 2,6 segundos cada vez que entra en ella por la noche, no es necesario que pongas los retardos para que enciendas las luces.
Tambien puedes implentar una rutina que si la luces ya estan encendidas que no entre en la funcion.

Saludos.
Hola compañero, gracias por responder, si es un arduino mega 2560. Soy novato en esto de arduino y por eso creía que estaba bien ponerles los corchetes entre funciones, como separando unas de otra.

No entiendo lo eso de poner funciones fuera del "lazo loop", si esta fuera de loop entonces como se ejecuta la función ?


Lo que pasa es que quiero que al encender las luces usando el sensor LDR (simulando la noche) , enciendan un por una y no todas a la vez por eso mism puse el delay .

Avatar de Usuario
mister_electronico
Mensajes: 122
Registrado: Mié Ene 15, 2014 8:44 pm
País: España
Ciudad: Asturias

Re: Como cambiar delay() por millis o time? arduino

#4 Mensaje por mister_electronico »

Si me equivoque atmega son todos me referia al mega 2560, lo preguntaba para la declaracion de la entradas.

Me referia a que pusieras las funciones fuera del blucle void loop

void loop
{
funcion_uno()
}

// esto es una funcion llamada desde el bucle loop.
void funcion_uno()
{

}

Esto hace mucho mas legible tu programa.

Mira este ejemplo de funciones en internet que te lo explica muy bien.
https://ardubasic.wordpress.com/2013/05 ... funciones/

Bueno si quieres mantener los retardos de encendido de luz tienes que tener en cuenta que cada vez que se entra en esta funcion tarda 2,8 segundo en realizarse.

Si no tienes bien conectada o desconectada el LDR puede que este entrandote constantemente.

Y no te olvides de resetear al final del programa la variable "estado".


Un saludo

brunomars09
Mensajes: 9
Registrado: Sab Abr 29, 2017 3:21 am
País: España
Ciudad: Barcelona

Re: Como cambiar delay() por millis o time? arduino

#5 Mensaje por brunomars09 »

Hola verdad que estoy perdido :( , con resetear a la variable te refieres con este comando

variable = null; o estado = 0;

hice lo poner las funciones fura del loop pero me sigue igual ;

Código: Seleccionar todo


void loop(){ 

 if( Serial.available()>0)   

   { estado = Serial.read();
  }
  
  if (estado=='s'){                 //si estado es igual a "s"  
    piralarmaState = digitalRead(piralarma);    //estado del pir alarma será igual al valor que lea del sensor

  if (piralarmaState==HIGH) {           //si hay intrusos
         digitalWrite(alarma, HIGH);           //activa alarma
         delay(500);
  if (estado=='t'){               //si estado es igual a "t"  
           digitalWrite(alarma, LOW);       //desactiva alarma
          }
        }
  }
  
  switch( estado)
  {
    case 'a':
    digitalWrite(led1, HIGH);    // primera luz del interior la casa 
    break;
    case 'b':
    digitalWrite(led1, LOW);
    break;
    
    case 'c':
    digitalWrite(led2, HIGH);
    break;
    case 'd':
    digitalWrite(led2, LOW);
    break;
    
    case 'e':
    digitalWrite(led3, HIGH);
    break;  
    case 'f':
    digitalWrite(led3, LOW);
    break;

    case 'g':
    digitalWrite(led4, HIGH);
    digitalWrite(led5, HIGH);        // luz pasillo ambas encienden a la vez 
    
    break;  
    case 'h':
    digitalWrite(led4, LOW);
    digitalWrite(led5, LOW);    // luz pasillo ambas se apagan a la vez 
    break;

    case 'i':
    digitalWrite(led6, HIGH);
    break;  
    case 'j':
    digitalWrite(led6, LOW);
    break;

    case 'k':
    digitalWrite(led7, HIGH);
    break;  
    case 'l':
    digitalWrite(led7, LOW);
    break;

    case 'm':
    digitalWrite(led8, HIGH);
    break;  
    case 'n':
    digitalWrite(led8, LOW);
    break;

    case 'o':
    digitalWrite(led9, HIGH);
    break;  
    case 'p':
    digitalWrite(led9, LOW);    // ultima luz del interior de la casa 
    break;

    case 'q':
    digitalWrite(led10, HIGH);
    digitalWrite(led11, HIGH);      // lucess del jardin  
    digitalWrite(led12, HIGH);
    digitalWrite(led13, HIGH);
    
    break;  
    case 'r':
    digitalWrite(led10, LOW);
    digitalWrite(led11, LOW);     //apagamos luces del jardin 
    digitalWrite(led12, LOW);
    digitalWrite(led13, LOW);
    break;

    case 't':
    digitalWrite(alarma, LOW);    // ultima luz del interior de la casa 
    break;
    
    case 'u':
    digitalWrite(ventilador, HIGH);
    break;
    case 'v':
    digitalWrite(ventilador, LOW);         // encendemos y apagamos ventilador
    break;

   estado = 0;
  }
  
    funcion_uno();
  }

void funcion_uno()

{

  LDRabc=analogRead(LDRpin);
    LDRvoltaje=LDRabc*(5.0/1023.0);
    Serial.print("voltaje LDR: ");
    delay(200);
    Serial.println(LDRvoltaje);
    
    if(LDRvoltaje<=1.20){
      digitalWrite(led10, HIGH);    
      delay(500);
      digitalWrite(led11, HIGH);      // luces del jardin encienden de noche
      delay(600);
      digitalWrite(led12, HIGH);
      delay(700);
      digitalWrite(led13, HIGH);
      delay(800);
  
      }

     else {
      
          digitalWrite(led10, LOW);
          digitalWrite(led11, LOW);   // luces del jardin se apagan de dia
          digitalWrite(led12, LOW);
          digitalWrite(led13, LOW);
          
          }
  
  humedad = dht.readHumidity();

  temp = dht.readTemperature();

  Serial.print("Temperatura:");
  Serial.print(temp);
  Serial.print("ºC Humedad: ");
  Serial.print(humedad);
  Serial.println("%");

  delay(500);

  if (temp < 22){//cambiar numero en funcion de lo que se desee
  digitalWrite(ventilador, LOW);
  }
else
  digitalWrite(ventilador,HIGH);

  }

 
// PROBLEMAS QUE TENEMOS: EN VENTILADOR FUNCIONA Y SE ENCIENDE AUTOMATICAMENTE, PERO UNA VEZ QUE LO PRENDEMOS Y APAGAMOS DIRECTAMENTE VIA  BLUETOOTH YA NO ENCIENDE DE FORMA AUTOMATICA POR ORDEN DEL SENSOR
// LOS LEDS ENCIENDEN CON RETRASO , CUANDO ENCENDEMOS LOS LEDS DEL JARDIN VIA BLUETOTTSE PRENDEN Y SE APAGAN, Y CUANDO LO HACEMOS DESDE EL SENSOR LDR SE APAGA LUEGO DE UNOS SEGUNDOS
// FALTA AGREGAR CODIGOS PARA MANEJAR 3 SERVOMOTORES  2 A 360ª SIMULANDO UNA PERSIANA Y 1 PARA LA PUERDA DEL GARAJE DE CASA (ABRIR/CERRAR) 
 

Y con respecto al LDR creo yo que esta bien conectado:
Imagen

Avatar de Usuario
mister_electronico
Mensajes: 122
Registrado: Mié Ene 15, 2014 8:44 pm
País: España
Ciudad: Asturias

Re: Como cambiar delay() por millis o time? arduino

#6 Mensaje por mister_electronico »

Efectivamente poner estado=0 lo estas reseteando, eliminas el estado anterior y evitas de nuevo que entre en el if correspondiente.

El problema es que no le estas poniendo al final del programa, lo estas poniendo dentro del lazo switch( estado), ponlo detras de la llamada a funcion_uno.

funcion_uno()
estado=0.
// PROBLEMAS QUE TENEMOS: EN VENTILADOR FUNCIONA Y SE ENCIENDE AUTOMATICAMENTE, PERO UNA VEZ QUE LO PRENDEMOS Y APAGAMOS DIRECTAMENTE VIA BLUETOOTH YA NO ENCIENDE DE FORMA AUTOMATICA POR ORDEN DEL SENSOR
En principio esto no deberia ser asi por que la variable temp es global y simpre estas haciendo la lectura del sensor de temperatura cuando entras en la funcion_uno()

Lo que tienes que tener en cuenta en tu programa con tu programa es que cuando tu le das la orden de apagar por bluetooth este parara pero si el sensor de temperatura le indica que tiene que encenderse se encendera inmediatamente nada mas entrar en la funcion_uno() y viceversa cuando le das la orden de encerer y el sensor le da la orden de apagar.

Si quieres que esto no ocurra tendras que poner una nueva condicion dentro de la condicion if que viene despues de la lectura automatica de temperatura.
// LOS LEDS ENCIENDEN CON RETRASO , CUANDO ENCENDEMOS LOS LEDS DEL JARDIN VIA BLUETOTTSE PRENDEN Y SE APAGAN, Y CUANDO LO HACEMOS DESDE EL SENSOR LDR SE APAGA LUEGO DE UNOS SEGUNDOS
Efectivamente cuando lo haces bluetooth no metes retardo en el encendido y apagado:

case 'q':
digitalWrite(led10, HIGH);
digitalWrite(led11, HIGH); // lucess del jardin
digitalWrite(led12, HIGH);
digitalWrite(led13, HIGH);

break;
case 'r':
digitalWrite(led10, LOW);
digitalWrite(led11, LOW); //apagamos luces del jardin
digitalWrite(led12, LOW);
digitalWrite(led13, LOW);
break;

Y cuando lo haces por sensor LDR si le pones retardo un retardo en el encendido.


LDRabc=analogRead(LDRpin);
LDRvoltaje=LDRabc*(5.0/1023.0);
Serial.print("voltaje LDR: ");
delay(200);
Serial.println(LDRvoltaje);

if(LDRvoltaje<=1.20){
digitalWrite(led10, HIGH);
delay(500);
digitalWrite(led11, HIGH); // luces del jardin encienden de noche
delay(600);
digitalWrite(led12, HIGH);
delay(700);
digitalWrite(led13, HIGH);
delay(800);

}

Te vuelvo a decir lo mismo que con la funcion de temperatura, tu le das la orden de apagar las luces con el bluetooth pero si nada mas el entrar en la funcion_uno() tiene la orden por LDR de encenderse se volvera a encender y viceversa.

Si quisiera que esto no ocurra deberias poner otra variable dentro de la funcion if de despues de lectura de LDR.

// FALTA AGREGAR CODIGOS PARA MANEJAR 3 SERVOMOTORES 2 A 360ª SIMULANDO UNA PERSIANA Y 1 PARA LA PUERDA DEL GARAJE DE CASA (ABRIR/CERRAR)
Poco a poco...


Saludos.

Avatar de Usuario
heli
Mensajes: 1952
Registrado: Mié Sep 06, 2006 7:28 am
País: España
Ciudad: Alcalá de Henares
Ubicación: Alcala de Henares (Madrid, España)
Contactar:

Re: Como cambiar delay() por millis o time? arduino

#7 Mensaje por heli »

El código escrito como lo tenías se entiende bastante mal, acostúmbrate a indentar correctmente para ver de un vistazo los segmentos de dependen de otros etc...

Código: Seleccionar todo

void loop()
{

  if( Serial.available()>0)
  {
    estado = Serial.read();
  }

  if (estado=='s')                 //si estado es igual a "s"
  {
    piralarmaState = digitalRead(piralarma);    //estado del pir alarma será igual al valor que lea del sensor
    if (piralarmaState==HIGH)            //si hay intrusos
    {
      digitalWrite(alarma, HIGH);           //activa alarma
      delay(500);
      if (estado=='t')               //si estado es igual a "t"  <- MAL, si estamos procesando por aqui es que estado=='s'
      {
        digitalWrite(alarma, LOW);       //desactiva alarma      <- por lo tanto nunca se ejecutara esto!!
      }
    }
  }

  switch( estado )
  {
    case 'a':
      digitalWrite(led1, HIGH);    // primera luz del interior la casa
      break;
    case 'b':
      digitalWrite(led1, LOW);
      break;

    case 'c':
      digitalWrite(led2, HIGH);
      break;
    case 'd':
      digitalWrite(led2, LOW);
      break;

    case 'e':
      digitalWrite(led3, HIGH);
      break;
    case 'f':
      digitalWrite(led3, LOW);
      break;

    case 'g':
      digitalWrite(led4, HIGH);
      digitalWrite(led5, HIGH);        // luz pasillo ambas encienden a la vez
      break;
    case 'h':
      digitalWrite(led4, LOW);
      digitalWrite(led5, LOW);    // luz pasillo ambas se apagan a la vez
      break;

    case 'i':
      digitalWrite(led6, HIGH);
      break;
    case 'j':
      digitalWrite(led6, LOW);
      break;

    case 'k':
      digitalWrite(led7, HIGH);
      break;
    case 'l':
      digitalWrite(led7, LOW);
      break;

    case 'm':
      digitalWrite(led8, HIGH);
      break;
    case 'n':
      digitalWrite(led8, LOW);
      break;

    case 'o':
      digitalWrite(led9, HIGH);
      break;
    case 'p':
      digitalWrite(led9, LOW);    // ultima luz del interior de la casa
      break;

    case 'q':
      digitalWrite(led10, HIGH);      // <- Para cambiar led10 aqui tienes que asegurarte que no lo haces abajo
      digitalWrite(led11, HIGH);      // lucess del jardin
      digitalWrite(led12, HIGH);
      digitalWrite(led13, HIGH);

      break;
    case 'r':
      digitalWrite(led10, LOW);
      digitalWrite(led11, LOW);     //apagamos luces del jardin
      digitalWrite(led12, LOW);
      digitalWrite(led13, LOW);
    break;

    case 't':
      digitalWrite(alarma, LOW);    // ultima luz del interior de la casa
      break;

    case 'u':
      digitalWrite(ventilador, HIGH);
      break;
    case 'v':
      digitalWrite(ventilador, LOW);         // encendemos y apagamos ventilador
      break;

  // estado = 0;     // MAL!!
  }
  estado = 0;      // <- aqui si
  funcion_uno();
}

void funcion_uno()
{

  LDRabc=analogRead(LDRpin);
  LDRvoltaje=LDRabc*(5.0/1023.0);
  Serial.print("voltaje LDR: ");
  delay(200);
  Serial.println(LDRvoltaje);

  if(LDRvoltaje<=1.20)              // <- Cuando esta condicion se cumpla se detendra loop mucho tiempo por culpa de los delay
  {
    digitalWrite(led10, HIGH);      // <- Para cambiar led10 aqui tienes que asegurarte que no lo cambias arriba
    delay(500);
    digitalWrite(led11, HIGH);      // luces del jardin encienden de noche
    delay(600);
    digitalWrite(led12, HIGH);
    delay(700);
    digitalWrite(led13, HIGH);
    delay(800);
  }
  else
  {
    digitalWrite(led10, LOW);
    digitalWrite(led11, LOW);   // luces del jardin se apagan de dia
    digitalWrite(led12, LOW);
    digitalWrite(led13, LOW);
  }
  humedad = dht.readHumidity();

  temp = dht.readTemperature();

  Serial.print("Temperatura:");
  Serial.print(temp);
  Serial.print("ºC Humedad: ");
  Serial.print(humedad);
  Serial.println("%");

  delay(500);    // <- Horrible, este delay en hace que loop solo se ejecute cada medio segundo!!

  if (temp < 22)//cambiar numero en funcion de lo que se desee
  {
    digitalWrite(ventilador, LOW);
  }
  else
    digitalWrite(ventilador,HIGH);

}
He marcado con <- algunos errores detectados...
Básicamente NO puedes activar/desactivar unas salidas en un bloque de código y luego hacerlo de nuevo en otro. Tienes que asegurarte de que, o entra a ejecutarse por una parte o lo hace por la otra. Si entra por las dos un bloque sobreescribirá lo que hizo el anterior y dará resultados erráticos dependiendo de los tiempos de procesamiento de cada bloque.
Otra forma es llevar las condiciones de un bloque a una variable y las del otro a otra variable y luego, con un OR de las variables, actuar las salidas.
¡No es imposible, lo que pasa es que no sabes como hacerlo!
Aka: no es difícil si sabes como.
http://heli.xbot.es

Avatar de Usuario
heli
Mensajes: 1952
Registrado: Mié Sep 06, 2006 7:28 am
País: España
Ciudad: Alcalá de Henares
Ubicación: Alcala de Henares (Madrid, España)
Contactar:

Re: Como cambiar delay() por millis o time? arduino

#8 Mensaje por heli »

Para usar millis tienes que cambiar la forma de pensar: no puedes parar nunca loop, las cosas se ejecutan o no dependiendo de las condiciones, pero loop no para nunca. Millis se usa así mas o menos:

Código: Seleccionar todo

  static long Time2=0;           
  long Millis = millis();

  if (Millis > Time2 + 500)            // Esta parte del codigo solo se ejecuta cada 500ms sin interrumpir el resto de loop
  {
    humedad = dht.readHumidity();
 
    temp = dht.readTemperature();

    Serial.print("Temperatura:");
    Serial.print(temp);
    Serial.print("ºC Humedad: ");
    Serial.print(humedad);
    Serial.println("%");
    Time2 = Millis;
  }  
¡No es imposible, lo que pasa es que no sabes como hacerlo!
Aka: no es difícil si sabes como.
http://heli.xbot.es

Avatar de Usuario
mister_electronico
Mensajes: 122
Registrado: Mié Ene 15, 2014 8:44 pm
País: España
Ciudad: Asturias

Re: Como cambiar delay() por millis o time? arduino

#9 Mensaje por mister_electronico »

Bueno lo que te decía antes de tener en cuenta que apagas las luces con el bluetooth y luego se encienden de orden del sensor, creo y esto es una creencia mía que lo que pretendes es que si es de noche y las luces están encendidas y tu le das la orden de que se apaguen con el bluetooth, evidentemente, las luces se queden ya apagadas y anular la automatización por LDR.


Me imagino que eso es lo que prentendes, si eso es así yo lo haría de la siguiente forma.

Junto a todas las variables globales temp, sensor, humedad, etc. creo otra variable.


int bandera =0;

Luego en el control de las luces por bluetooth haría lo siguiente:
case 'q':
digitalWrite(led10, HIGH);
digitalWrite(led11, HIGH); // lucess del jardin
digitalWrite(led12, HIGH);
digitalWrite(led13, HIGH);
bandera =1 ; Esta bandera puesta a 1 hará que el control por LDR ya no sea posible. y se quedaran siempre encendidas hasta una nueva orden de bluetooth
break;

case 'r':
digitalWrite(led10, LOW);
digitalWrite(led11, LOW); //apagamos luces del jardin
digitalWrite(led12, LOW);
digitalWrite(led13, LOW);
bandera =1 ; Esta bandera puesta a 1 hará que el control por LDR ya no sea posible. y se quedaran
siempre apagadas hasta una nueva orden de bluetooth

break;

case 's':
bandera = 0; Con esta nueva orden de bluetooth permito que la celula LDR actue.
break;


Y por fin en la funcion_uno dentro del control de la LDR haria lo siguiente en la linea del if:


if(LDRvoltaje<=1.20 && bandera = 0 ){

Chequea si la bandera esta puesta a cero y si no es así no actúa la LDR.

Lo mismo puede hacer con la variable temperatura pero claro utilizando otra bandera ejemplo bandera2
y así con otras variables.

Perdona que me anticipe a los acontecimientos, pero a lo mejor es eso lo que quieres hacer.

Un saludo

brunomars09
Mensajes: 9
Registrado: Sab Abr 29, 2017 3:21 am
País: España
Ciudad: Barcelona

Re: Como cambiar delay() por millis o time? arduino

#10 Mensaje por brunomars09 »

Eh dejado el codigo asi las luces de la casa van bien, la alarma tambien, los problemas que me dan son con las luces del jardin, les afecta el delay del sensor de temperatura cuando las enciendo via bluetooth.

Cuando enciendo las luces del jardin por el sensor ldr, no permancen prendidas.


Si escribo estado = 0; la alarma deja de funcionar

dejo un link con un video para que vean lo que sucede

https://www.youtube.com/watch?v=BC1kevBajYw



Código: Seleccionar todo


#include <DHT.h>

int sensor = 22; 
int temp, humedad;

DHT dht (sensor, DHT11);

int led1 = 40;      //Luz 1 Comedor
int led2 = 41;      //Luz_2_Comedor
int led3 = 42;      //Luz_Cocina
int led4 = 43;      //Luz_1_Pasillo 
int led5 = 44;      //Luz_1_Pasillo 
int led6 = 45;      //Luz_Hab 1
int led7 = 46;      //Luz_Hab 1
int led8 = 47;      //Luz_Baño
int led9 = 48;      //Luz_Garaje
int led10 = 49;     //Luz_1_Jardin
int led11 = 50;     //Luz_2_Jardin
int led12 = 51;     //Luz_3_Jardin
int led13 = 52;     //Luz_4_Jardin

int ventilador= 6;

//bluetooth 
int estado = 0;

int LDRpin=A1;            // define el pin conectado al LDR
int LDRabc=0;
float LDRvoltaje=0;         // variable tipo flotante

int alarma=39;            //alarma contra intrusos y a la vez de incendios
int piralarma=7;         //sensor pir que detecta movimiento
int piralarmaState;       //variable para almacenar el valor del sensor pir


void setup(){
  
   
  Serial.begin(9600);

  pinMode(LDRpin, INPUT);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(led5, OUTPUT);
  pinMode(led6, OUTPUT);
  pinMode(led7, OUTPUT);
  pinMode(led8, OUTPUT);
  pinMode(led9, OUTPUT);
  pinMode(led10, OUTPUT);
  pinMode(led11, OUTPUT);
  pinMode(led12, OUTPUT);
  pinMode(led13, OUTPUT);

  pinMode(alarma, OUTPUT); 
  pinMode(piralarma, INPUT);


  pinMode(ventilador,OUTPUT);     //configuracion del ventilador


}
 
void loop(){  
 if( Serial.available()>0)   

   { estado = Serial.read();
  }
  
  if (estado=='s'){                 //si estado es igual a "s"  
    piralarmaState = digitalRead(piralarma);    //estado del pir alarma será igual al valor que lea del sensor

  if (piralarmaState==HIGH) {           //si hay intrusos
         digitalWrite(alarma, HIGH);           //activa alarma
          delay(500);
         
  if (estado=='t'){               //si estado es igual a "t"  
           digitalWrite(alarma, LOW);       //desactiva alarma
          }
        }
  }
  
  switch( estado)
  {
    case 'a':
    digitalWrite(led1, HIGH);    // primera luz del interior la casa 
    break;
    case 'b':
    digitalWrite(led1, LOW);
    break;
    
    case 'c':
    digitalWrite(led2, HIGH);
    break;
    case 'd':
    digitalWrite(led2, LOW);
    break;
    
    case 'e':
    digitalWrite(led3, HIGH);
    break;  
    case 'f':
    digitalWrite(led3, LOW);
    break;

    case 'g':
    digitalWrite(led4, HIGH);
    digitalWrite(led5, HIGH);        // luz pasillo ambas encienden a la vez 
    
    break;  
    case 'h':
    digitalWrite(led4, LOW);
    digitalWrite(led5, LOW);    // luz pasillo ambas se apagan a la vez 
    break;

    case 'i':
    digitalWrite(led6, HIGH);
    break;  
    case 'j':
    digitalWrite(led6, LOW);
    break;

    case 'k':
    digitalWrite(led7, HIGH);
    break;  
    case 'l':
    digitalWrite(led7, LOW);
    break;

    case 'm':
    digitalWrite(led8, HIGH);
    break;  
    case 'n':
    digitalWrite(led8, LOW);
    break;

    case 'o':
    digitalWrite(led9, HIGH);
    break;  
    case 'p':
    digitalWrite(led9, LOW);    // ultima luz del interior de la casa 
    break;

    case 'q':
    digitalWrite(led10, HIGH);
    digitalWrite(led11, HIGH);      // lucess del jardin  
    digitalWrite(led12, HIGH);
    digitalWrite(led13, HIGH);
    
    break;  
    case 'r':
    digitalWrite(led10, LOW);
    digitalWrite(led11, LOW);     //apagamos luces del jardin 
    digitalWrite(led12, LOW);
    digitalWrite(led13, LOW);
    break;

    case 't':
    digitalWrite(alarma, LOW);    // ultima luz del interior de la casa 
    break;
    
    case 'u':
    digitalWrite(ventilador, HIGH);
    break;
    case 'v':
    digitalWrite(ventilador, LOW);         // encendemos y apagamos ventilador
    break;


  }
  

  
   
  funcion_uno();
  
  }

  void funcion_uno()
{

  LDRabc=analogRead(LDRpin);
  LDRvoltaje=LDRabc*(5.0/1023.0);
 
  if(LDRvoltaje<=1.20)              // <- Cuando esta condicion se cumpla se detendra loop mucho tiempo por culpa de los delay, como evito  eso sin quitar los delay ?
  {
    digitalWrite(led10, HIGH);      
    delay(500);
    digitalWrite(led11, HIGH);      // luces del jardin encienden de noche
    delay(600);
    digitalWrite(led12, HIGH);
    delay(700);
    digitalWrite(led13, HIGH);
    delay(800);
  }
  else
  {
    digitalWrite(led10, LOW);
    digitalWrite(led11, LOW);   // luces del jardin se apagan de dia
    digitalWrite(led12, LOW);
    digitalWrite(led13, LOW);
  }

  static long Time2=0;           
  long Millis = millis();

  if (Millis > Time2 + 7000)            // Esta parte del codigo solo se ejecuta cada 500ms sin interrumpir el resto de loop
  {
    humedad = dht.readHumidity();
 
    temp = dht.readTemperature();

    Serial.print("Temperatura:");
    Serial.print(temp);
    Serial.print("ºC Humedad: ");
    Serial.print(humedad);
    Serial.println("%");
    Time2 = Millis;
  } 

   if (temp < 27)//cambiar numero en funcion de lo que se desee
  {
    digitalWrite(ventilador, LOW);
  }
  else
    digitalWrite(ventilador,HIGH);

}
   
// PROBLEMAS QUE TENEMOS: EN VENTILADOR FUNCIONA Y SE ENCIENDE AUTOMATICAMENTE SEGUND ODREN DEL SENSOR DE TEMPERATURA , PERO UNA VEZ QUE LO PRENDEMOS Y APAGAMOS DIRECTAMENTE DESDE EL BLUETOOTH YA NO ENCIENDE DE FORMA AUTOMATICA POR EL SENSOR Y CREA UN ESPECIE DE COMFLICTO CON EL BLUETOOTH
// TODOS LOS LEDS ENCIENDEN DE LA CASA ENCIENDEN SIM PROBLEMA, CUANDO ENCENDEMOS LOS LEDS DEL JARDIN VIA BLUETOTTSE PRENDEN, PERO  SE APAGAN CON CADA LECTURA DEL SENSOR DE TEMPERATURA, PERO NO SE PAGAN DEL TODO VUELVEN A PRENDERSE  , Y CUANDO LO HACEMOS DESDE EL SENSOR LDR ENCIENDE CADA LED UNO POR UNO, LO CUAL ESTA BIEN,  PERO AL PRENDERSE EL ULTIMO, SE APAGAN  Y EMPIENZA OTRA VEZ EL CICLO 


Bueno lo que te decía antes de tener en cuenta que apagas las luces con el bluetooth y luego se encienden de orden del sensor, creo y esto es una creencia mía que lo que pretendes es que si es de noche y las luces están encendidas y tu le das la orden de que se apaguen con el bluetooth, evidentemente, las luces se queden ya apagadas y anular la automatización por LDR.


Me imagino que eso es lo que prentendes, si eso es así yo lo haría de la siguiente forma.
No lo que yo pretendo es solo hacer la simulacion de que las luces del jardin se encieden de noche, tapando el ldr y ya esta , pero no apagarlas via bluetooth mientras estan encendidas con el LDR.

if (estado=='s') //si estado es igual a "s"
{
piralarmaState = digitalRead(piralarma); //estado del pir alarma será igual al valor que lea del sensor
if (piralarmaState==HIGH) //si hay intrusos
{
digitalWrite(alarma, HIGH); //activa alarma
delay(500);
if (estado=='t') //si estado es igual a "t" <- MAL, si estamos procesando por aqui es que estado=='s'
{
digitalWrite(alarma, LOW); //desactiva alarma <- por lo tanto nunca se ejecutara esto!!
}
}
Sin embargo si me funciona bien, al darle la orden desde buetooth




Gracias por responder, soy nuevo con esto de programación con arduino y aprecio mucho cualquier ayuda

Responder

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado