Pages: [1]   Go Down
Author Topic: Detector de presencia con una resistenicia fotoeléctrica (LDR) -Tiene otros usos  (Read 3469 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 35
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

- Este programa es un disparador, que activa una salida lógica si detecta un cambio de tensión en su entrada analógica, dentro de un rango establecido por el usuario.
- Las aplicaciones pueden ser por ejemplo, como detector en alguna aplicación que use un sensor que pueda producir variaciones de tensión.
- El circuito de ejemplo usa una resistencia fotoeléctrica (LDR) para hacer un detector de presencia o de movimiento, de los del tipo PIR.

- NOTA: ESTE DETECTOR ACTIVA EL LED SI LA VARIACIÓN DE TENSIÓN SUPERA UN DETERMINADO RANGO CON RESPECTO A LA ÚLTIMA VEZ QUE SE ACTIVO.


Code:
/*
- Este programa es un disparador, que activa una salida lógica si detecta un cambio de tensión en su entrada analógica, dentro de un rango establecido por el usuario.
- Las aplicaciones pueden ser por ejemplo, como detector en alguna aplicación que use un sensor que pueda producir variaciones de tensión.
- El circuito de ejemplo usa una resistencia fotoeléctrica (LDR) para hacer un detector de presencia o de movimiento, de los del tipo PIR.

CONEXIONADO.

CONECTAR LA LDR AL TERMINAL POSITIVO
CONECTAR UNA RESISTENCIA DE 33k EN SERIE CON LA RESISTENCIA FOTOELÉCTRICA (LDR) Y CONECTAR EL EXTREMO LIBRE A MASA.
CONECTAR LA ENTRADA ANALÓGICA "CERO" DEL ARDUINO ENTRE LA RESISTENCIA LDR Y LA RESISTENCIA DE 33k. ES DECIR, ENTRE LOS DOS COMPONENTES.

CONECTAR UN EL ÁNODO DE UN DIODO LED AL TERMINA DIGITAL 2
CONECTAR EL CÁTODO DEL DIODO LED A UNA RESISTENCIA DE 220 OHMIOS Y LA RESISTENCIA A MASA.

FUNCIONAMIENTO

EL LED SE ENCENDERÁ SI LA VARIACIÓN DE TENSIÓN DETECTADA POR LA ENTRADA ANALÓGICA 0 DEL ARDUINO SUPERA UN DETERMINADO RANGO, ESTABLECIDO POR LA CONSTANTE.

Si pasamos la mano frente a la resistencia LDR el LED se encenderá, por la variación de tensión detectada por el arduino en su entrada.
Si al LDR lo colocamos en el interior de un capuchón de un bolígrafo BIC (de esos que tienen un agujero), usaremos el capuchón como cámara oscura rudimentaria, que permitirá a la LDR detectar el movimiento a distancias mayores.

ESTE CIRCUITO A SIDO PROBADO Y FUNCIONA CORRECTAMENTE
EL USUARIO TENDRÁ QUE AJUSTAR LA SENSIBILIDAD DEL DISPOSITIVO, CAMBIANDO EL VALOR DE LA VARIABLE LLAMADA RANGO QUE POR DEFECTO ESTÁN EN 5, PUDIENDO SE PONER ENTRE 1 (MÁXIMA SENSIBILIDAD) O VALORES MAYORES, QUE DEPENDERÁN DE LA TENSIÓN DE ENTRADA Y LAS VARIACIONES.

AUTOR: Mario R.P - mariorp@terra.es - 13-6-2012

*/
const long rango=5; // este es el rango por el que se disparará la salida 2 y pasa a estado lógico 1
const long tiempo=1000; // tiempo que permanecerá activa la salida 2 en caso de pasar a estado lógico 1
long ultimamedicion; // contiene el valor de la última medición que disparó a lógico 1, la salida 2

void setup() {
  Serial.begin(9600);
  pinMode(A0, INPUT);
  pinMode(2, OUTPUT);
}

void loop() {
  
  long sensorValue = analogRead(A0);
  
  if (sensorValue >= ( ultimamedicion+rango)) // La salida 2 pasa a 1 lógico si la tensión medida en la entrada analógica 0 es mayor que la anterior lectura + la tensión de RANGO
  {
    digitalWrite(2, HIGH);
    ultimamedicion = sensorValue;
    delay(tiempo);
  }
  else  // La salida 2 pasa a 0 si la tensión medida en la entrada analógica 0 no es mayor
  {
  digitalWrite(2, LOW);
  }
    
  
  if (sensorValue <= ( ultimamedicion-rango))  // La salida 2 pasa a 1 lógico si la tensión medida en la entrada analógica 0 es menor que la anterior lectura - la tensión de RANGO
  {
    digitalWrite(2, HIGH);      
    ultimamedicion = sensorValue;
    delay(tiempo);
  }
  else
  {
  digitalWrite(2, LOW);
  }
    
  
  // Serial.println(sensorValue); // Por si quieres ver por el puerto serie las lecturas tomadas
  // Serial.println(ultimamedicion); // Por si quieres ver por el puerto serie las lecturas tomadas

}


« Last Edit: June 13, 2012, 02:31:10 pm by lm386 » Logged

Spain
Offline Offline
Full Member
***
Karma: 0
Posts: 191
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Muchas gracias por aportar otro ejemplo al foro.  smiley smiley smiley

Como en el anterior ejemplo que pusiste, me gustaría comentarte otro par de cosas para mejorarlo:

No inicializas ultimamedicion, con lo que probablemente se inicie a cero y el código empiece con una activación por no estar la medida en el rango.

Una vez activas la salida, utilizas un delay para parar el programa. Durante ese tiempo la señal de entrada ha podido variar mucho y en ambos sentidos, esos cambios los has perdido y no los tienes controlados. Haces una medida cada ciclo (supongamos que el ciclo del programa que propones tardar 2-4 milisegundos), cuando activas la salida paras el bucle durante 1000 milisegundos. En ese tiempo podrías haber detectado de 250 a 500 cambios en el valor leído que se te han escapado.

Al poner un delay de 1 segundo, supongo que el tiempo de reacción del código no es crítico y pretendes detectar variaciones de la tensión de entrada, no picos ni fluctuaciones rápidas. Como en el ejemplo de los leds que pusiste, utilizas una única lectura para actuar. Para evitar problemas con picos y fluctuaciones (como pasaba en ese ejemplo también) deberías realizar una media de medidas y actuar a partir de ese valor.

Por último, me gusta mucho  smiley-grin (de verdad) que hayas puesto casi tantas líneas de comentarios como de código y hayas dejado las llamadas a serial.print comentadas (aunque no has comentado el begin smiley-razz ) . Esa es la forma de que todos los que quieren utilizar estos ejemplos puedan entenderlos rápidamente y aprender.

Permíteme que aplique estos cambios y me dices que te parece el resultado (a lo mejor no es lo que tú esperabas que hiciese, así que no dudes en decirmelo).

Code:
/*
- Este programa es un disparador, que activa una salida lógica si detecta un cambio de tensión en su entrada analógica, dentro de un rango establecido por el usuario.
- Las aplicaciones pueden ser por ejemplo, como detector en alguna aplicación que use un sensor que pueda producir variaciones de tensión.
- El circuito de ejemplo usa una resistencia fotoeléctrica (LDR) para hacer un detector de presencia o de movimiento, de los del tipo PIR.

CONEXIONADO.

CONECTAR LA LDR AL TERMINAL POSITIVO
CONECTAR UNA RESISTENCIA DE 33k EN SERIE CON LA RESISTENCIA FOTOELÉCTRICA (LDR) Y CONECTAR EL EXTREMO LIBRE A MASA.
CONECTAR LA ENTRADA ANALÓGICA "CERO" DEL ARDUINO ENTRE LA RESISTENCIA LDR Y LA RESISTENCIA DE 33k. ES DECIR, ENTRE LOS DOS COMPONENTES.

CONECTAR UN EL ÁNODO DE UN DIODO LED AL TERMINA DIGITAL 2
CONECTAR EL CÁTODO DEL DIODO LED A UNA RESISTENCIA DE 220 OHMIOS Y LA RESISTENCIA A MASA.

FUNCIONAMIENTO

EL LED SE ENCENDERÁ SI LA VARIACIÓN DE TENSIÓN DETECTADA POR LA ENTRADA ANALÓGICA 0 DEL ARDUINO SUPERA UN DETERMINADO RANGO, ESTABLECIDO POR LA CONSTANTE.

Si pasamos la mano frente a la resistencia LDR el LED se encenderá, por la variación de tensión detectada por el arduino en su entrada.
Si al LDR lo colocamos en el interior de un capuchón de un bolígrafo BIC (de esos que tienen un agujero), usaremos el capuchón como cámara oscura rudimentaria, que permitirá a la LDR detectar el movimiento a distancias mayores.

ESTE CIRCUITO A SIDO PROBADO Y FUNCIONA CORRECTAMENTE
EL USUARIO TENDRÁ QUE AJUSTAR LA SENSIBILIDAD DEL DISPOSITIVO, CAMBIANDO EL VALOR DE LA VARIABLE LLAMADA RANGO QUE POR DEFECTO ESTÁN EN 5, PUDIENDO SE PONER ENTRE 1 (MÁXIMA SENSIBILIDAD) O VALORES MAYORES, QUE DEPENDERÁN DE LA TENSIÓN DE ENTRADA Y LAS VARIACIONES.

*/

const long rango=5; // este es el rango por el que se disparará la salida 2 y pasa a estado lógico 1
const long tiempo=1000; // tiempo que permanecerá activa la salida 2 en caso de pasar a estado lógico 1
const char num_medidas_media=128;  // numero de medidas a tomar para hacer la media
long ultimamedicion; // contiene el valor de la última medición que disparó a lógico 1, la salida 2
char num_medidas; // número de medidas tomadas para la media
long valor_medio; // valor medio para comparar con los umbrales
unsigned long inicio_pulso;  // momento en el que se detecta la salida del rango;

void setup() {
//  Serial.begin(9600);
  // inicialización de los pines
  pinMode(A0, INPUT);
  pinMode(2, OUTPUT);
 
  // inicilización de variables
  inicio_pulso = 0;
  num_medidas = 0;
  valor_medio = 0;
 
  // inicialización de ultimamedicion mediante una primera media
  while(num_medidas<num_medidas_media)
  {
    valor_medio +=analogRead(A0);
    num_medidas++;
    delay(10);
  }
  ultimamedicion = valor_medio/num_medidas_media;

  num_medidas = 0;
  valor_medio = 0;
}

void loop()
{
  valor_medio += analogRead(A0); // vamos sumando valores (Cuidado!!! Si se utilizan muchas medidas para la media podría desbordar)
  num_medidas++;
 
  if(num_medidas == num_medidas_media)  // ya tenemos las "num_medidas_media" medidas
  {
    valor_medio = valor_medio/num_medidas_media; // Dividimos para calcular la media

    if (valor_medio >= (ultimamedicion+rango)) // La salida 2 pasa a 1 lógico si la tensión medida en la entrada analógica 0 es mayor que la anterior lectura + la tensión de RANGO
    {
      digitalWrite(2, HIGH);
      ultimamedicion = valor_medio;
      inicio_pulso = millis();
    }
   
    if (valor_medio <= (ultimamedicion-rango))  // La salida 2 pasa a 1 lógico si la tensión medida en la entrada analógica 0 es menor que la anterior lectura - la tensión de RANGO
    {
      digitalWrite(2, HIGH);     
      ultimamedicion = valor_medio;
      inicio_pulso = millis();
    }

    // Serial.println(valor_medio); // Por si quieres ver por el puerto serie las lecturas tomadas
    // Serial.println(ultimamedicion); // Por si quieres ver por el puerto serie las lecturas tomadas

    // inicializamos los valores para calcular la siguiente media
    num_medidas = 0;  // inicializamos las medidas
    valor_medio = 0;  // inicializamos el valor para la siguiente media
    // Si quesieramos utilizar la media que acabamos de calcular como primer valor para la siguiente media:
    // no reiniciamos valor_medio y num_medidas = 1;
  }
 
  if((inicio_pulso+tiempo) >= millis()) // Ha pasado "tiempo" desde la última detección
    digitalWrite(2, LOW); // La salida 2 pasa a 0 si la tensión medida en la entrada analógica 0 no esta fuera de rango
}
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 35
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Gracias por tus comentarios y por tú código.

Efectivamente la lógica que planteas está bien, pero cuando meto el programa en el arduino no hace nada. Es decir, que hay algún fallo o algo y no funciona.

Como consejo general a todos, recomiendo probar siempre el código en una placa y ver que pasa, ya que teóricamente las cosas deben de funcionar de una manera, pero casi nunca funciona de esa manera  smiley-lol.

Mi código está simplificado al máximo para que cualquiera lo pueda adaptar rápidamente el código a su proyecto.

Efectivamente al iniciarse el programa se enciende el LED, pero eso puede ser bueno o malo, dependiendo de la aplicación, así que por ese motivo no amplio mi código, por que solo es una base, para que la gente lo adapte a sus necesidades.

Y nuevamente gracias por el esfuerzo y molestarte el mejorar el código.
Logged

Spain
Offline Offline
Full Member
***
Karma: 0
Posts: 191
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Tienes razón, falla, he puesto el código que estaba mal

En la versión correcta hay que cambiar:
Code:
if((inicio_pulso+tiempo) >= millis()) // Ha pasado "tiempo" desde la última detección
por
Code:
if((inicio_pulso+tiempo) <= millis()) // Ha pasado "tiempo" desde la última detección

Lo había modificado para poner millis al final y me he olvidado de cambiar el signo  smiley-cry

De todas formas, espero que no te tomes a mal los comentarios, solo trato de mostrarte posibles mejoras  (desde mi punto de vista) y, como ya dijimos en el otro post, jugar con el código que propones. Y si además, aprendemos algo...pues mejor que mejor.

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 35
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

 smiley-mr-green No te lo tomes a mal, pero sigue sin funcionar o yo no lo he corregido bien, no se.

Y no, por supuesto que no me lo tomo a mal, esto es un juego. Más triste sería que pusiese un código y no recibiese ninguna respuesta.

Para el resto de foreros, les agradecería que me hiciesen un poco la pelota o algo, con un simple gracias vale. smiley-lol

El código que le metí al arduino es este, con la corrección que has mencionado, pero no hace nada.

Un cordial saludo.

Code:
/*
- Este programa es un disparador, que activa una salida lógica si detecta un cambio de tensión en su entrada analógica, dentro de un rango establecido por el usuario.
- Las aplicaciones pueden ser por ejemplo, como detector en alguna aplicación que use un sensor que pueda producir variaciones de tensión.
- El circuito de ejemplo usa una resistencia fotoeléctrica (LDR) para hacer un detector de presencia o de movimiento, de los del tipo PIR.

CONEXIONADO.

CONECTAR LA LDR AL TERMINAL POSITIVO
CONECTAR UNA RESISTENCIA DE 33k EN SERIE CON LA RESISTENCIA FOTOELÉCTRICA (LDR) Y CONECTAR EL EXTREMO LIBRE A MASA.
CONECTAR LA ENTRADA ANALÓGICA "CERO" DEL ARDUINO ENTRE LA RESISTENCIA LDR Y LA RESISTENCIA DE 33k. ES DECIR, ENTRE LOS DOS COMPONENTES.

CONECTAR UN EL ÁNODO DE UN DIODO LED AL TERMINA DIGITAL 2
CONECTAR EL CÁTODO DEL DIODO LED A UNA RESISTENCIA DE 220 OHMIOS Y LA RESISTENCIA A MASA.

FUNCIONAMIENTO

EL LED SE ENCENDERÁ SI LA VARIACIÓN DE TENSIÓN DETECTADA POR LA ENTRADA ANALÓGICA 0 DEL ARDUINO SUPERA UN DETERMINADO RANGO, ESTABLECIDO POR LA CONSTANTE.

Si pasamos la mano frente a la resistencia LDR el LED se encenderá, por la variación de tensión detectada por el arduino en su entrada.
Si al LDR lo colocamos en el interior de un capuchón de un bolígrafo BIC (de esos que tienen un agujero), usaremos el capuchón como cámara oscura rudimentaria, que permitirá a la LDR detectar el movimiento a distancias mayores.

ESTE CIRCUITO A SIDO PROBADO Y FUNCIONA CORRECTAMENTE
EL USUARIO TENDRÁ QUE AJUSTAR LA SENSIBILIDAD DEL DISPOSITIVO, CAMBIANDO EL VALOR DE LA VARIABLE LLAMADA RANGO QUE POR DEFECTO ESTÁN EN 5, PUDIENDO SE PONER ENTRE 1 (MÁXIMA SENSIBILIDAD) O VALORES MAYORES, QUE DEPENDERÁN DE LA TENSIÓN DE ENTRADA Y LAS VARIACIONES.

*/

const long rango=5; // este es el rango por el que se disparará la salida 2 y pasa a estado lógico 1
const long tiempo=1000; // tiempo que permanecerá activa la salida 2 en caso de pasar a estado lógico 1
const char num_medidas_media=128;  // numero de medidas a tomar para hacer la media
long ultimamedicion; // contiene el valor de la última medición que disparó a lógico 1, la salida 2
char num_medidas; // número de medidas tomadas para la media
long valor_medio; // valor medio para comparar con los umbrales
unsigned long inicio_pulso;  // momento en el que se detecta la salida del rango;

void setup() {
//  Serial.begin(9600);
  // inicialización de los pines
  pinMode(A0, INPUT);
  pinMode(2, OUTPUT);
 
  // inicilización de variables
  inicio_pulso = 0;
  num_medidas = 0;
  valor_medio = 0;
 
  // inicialización de ultimamedicion mediante una primera media
  while(num_medidas<num_medidas_media)
  {
    valor_medio +=analogRead(A0);
    num_medidas++;
    delay(10);
  }
  ultimamedicion = valor_medio/num_medidas_media;

  num_medidas = 0;
  valor_medio = 0;
}

void loop()
{
  valor_medio += analogRead(A0); // vamos sumando valores (Cuidado!!! Si se utilizan muchas medidas para la media podría desbordar)
  num_medidas++;
 
  if(num_medidas == num_medidas_media)  // ya tenemos las "num_medidas_media" medidas
  {
    valor_medio = valor_medio/num_medidas_media; // Dividimos para calcular la media

    if (valor_medio >= (ultimamedicion+rango)) // La salida 2 pasa a 1 lógico si la tensión medida en la entrada analógica 0 es mayor que la anterior lectura + la tensión de RANGO
    {
      digitalWrite(2, HIGH);
      ultimamedicion = valor_medio;
      inicio_pulso = millis();
    }
   
    if (valor_medio <= (ultimamedicion-rango))  // La salida 2 pasa a 1 lógico si la tensión medida en la entrada analógica 0 es menor que la anterior lectura - la tensión de RANGO
    {
      digitalWrite(2, HIGH);     
      ultimamedicion = valor_medio;
      inicio_pulso = millis();
    }

    // Serial.println(valor_medio); // Por si quieres ver por el puerto serie las lecturas tomadas
    // Serial.println(ultimamedicion); // Por si quieres ver por el puerto serie las lecturas tomadas

    // inicializamos los valores para calcular la siguiente media
    num_medidas = 0;  // inicializamos las medidas
    valor_medio = 0;  // inicializamos el valor para la siguiente media
    // Si quesieramos utilizar la media que acabamos de calcular como primer valor para la siguiente media:
    // no reiniciamos valor_medio y num_medidas = 1;
  }
 
 if((inicio_pulso+tiempo) <= millis()) // Ha pasado "tiempo" desde la última detección
    digitalWrite(2, LOW); // La salida 2 pasa a 0 si la tensión medida en la entrada analógica 0 no esta fuera de rango
}
Logged

Spain
Offline Offline
Full Member
***
Karma: 0
Posts: 191
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Otra vez, tenías razón  smiley-cry smiley-cry smiley-cry smiley-cry smiley-cry

Hay que cambiar los tipos de las variables de char a byte. Es un cambio que había hecho al quitar los comandos serie con los que probaba el código.

Nunca había tenido problemas hasta ahora con el tipo char, pero...eso que he aprendido gracias a tí.

Cambiar:
Code:
const char num_medidas_media=128;  // numero de medidas a tomar para hacer la media
long ultimamedicion; // contiene el valor de la última medición que disparó a lógico 1, la salida 2
char num_medidas; // número de medidas tomadas para la media
por:
Code:
const byte num_medidas_media=128;  // numero de medidas a tomar para hacer la media
long ultimamedicion; // contiene el valor de la última medición que disparó a lógico 1, la salida 2
byte num_medidas; // número de medidas tomadas para la media

De todas formas, cuando tenga un poco más de tiempo, lo terminaré de comprobar con hardware real (ahora lo he hecho a base de comunicación por puerto serie porque no tengo sensores a mano).

Si lo pruebas, me comentas el resultado...Ya es por orgullo personal (no va a poder esa plaquita azul conmigo, vamos, hasta ahí podríamos llegar)

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 35
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Aquí pongo el código modificado y mejorado, que permite al detector adaptarse a cambios de luz progresivos, normales en ambientes iluminados con luz natural. El anterior código no tenía en cuanta los cambios de tensión suaves y progresivos producidos en la fotoresistencia, debido a los cambios naturales de la intensidad de la luz, que varían dependiendo de la hora del día. El actual código si los tiene en cuenta y se reajusta automáticamente cada 10 segundos. Este plazo de tiempo se puede cambiar con facilidad, cambiando la variable "tiempoadaptacion".

También se a modificado el código, para que no se active el detector nada más encender el arduino, evitando así, falsos positivos al arrancar el programa.

Code:
/*
- Este programa es un disparador, que activa una salida lógica si detecta un cambio de tensión en su entrada analógica, dentro de un rango establecido por el usuario.
- Las aplicaciones pueden ser por ejemplo, como detector en alguna aplicación que use un sensor que pueda producir variaciones de tensión.
- El circuito de ejemplo usa una resistencia fotoeléctrica (LDR) para hacer un detector de presencia o de movimiento, de los del tipo PIR.

CONEXIONADO.

CONECTAR LA LDR AL TERMINAL POSITIVO
CONECTAR UNA RESISTENCIA DE 33k EN SERIE CON LA RESISTENCIA FOTOELÉCTRICA (LDR) Y CONECTAR EL EXTREMO LIBRE A MASA.
CONECTAR LA ENTRADA ANALÓGICA "CERO" DEL ARDUINO ENTRE LA RESISTENCIA LDR Y LA RESISTENCIA DE 33k. ES DECIR, ENTRE LOS DOS COMPONENTES.

CONECTAR UN EL ÁNODO DE UN DIODO LED AL TERMINA DIGITAL 2
CONECTAR EL CÁTODO DEL DIODO LED A UNA RESISTENCIA DE 220 OHMIOS Y LA RESISTENCIA A MASA.

FUNCIONAMIENTO

EL LED SE ENCENDERÁ SI LA VARIACIÓN DE TENSIÓN DETECTADA POR LA ENTRADA ANALÓGICA 0 DEL ARDUINO SUPERA UN DETERMINADO RANGO, ESTABLECIDO POR LA CONSTANTE.

Si pasamos la mano frente a la resistencia LDR el LED se encenderá, por la variación de tensión detectada por el arduino en su entrada.
Si al LDR lo colocamos en el interior de un capuchón de un bolígrafo BIC (de esos que tienen un agujero), usaremos el capuchón como cámara oscura rudimentaria, que permitirá a la LDR detectar el movimiento a distancias mayores.

ESTE CIRCUITO A SIDO PROBADO Y FUNCIONA CORRECTAMENTE

EL USUARIO TENDRÁ QUE AJUSTAR LA SENSIBILIDAD DEL DISPOSITIVO, CAMBIANDO EL VALOR DE LA VARIABLE LLAMADA RANGO QUE POR DEFECTO ESTÁN EN 5, PUDIENDO SE PONER ENTRE 1 (MÁXIMA SENSIBILIDAD) O VALORES MAYORES, QUE DEPENDERÁN DE LA TENSIÓN DE ENTRADA Y LAS VARIACIONES.

ULTIMA MEJORA

EL PROGRAMA DISPONE DE UN BUCLE FOR, QUE PERMITE AL PROGRAMA IGNORAR LOS CAMBIOS SUAVES, CORRESPONDIENTE A CAMBIOS PRODUCIDOS A INTERVALOS SUPERIORES A LOS 10 SEGUNDOS.

TAMBIÉN SE A MODIFICADO EL CÓDIGO PARA QUE NO SE ACTIVE EL LED NADA MÁS PONER EN FUNCIONAMIENTO EL ARDUINO, COSA QUE ANTES SÍ HACÍA, DANDO ASÍ, UN FALSO POSITIVO.

*/
const long tiempoadaptacion=10; // tiempo de adaptación a los cambios progresivos. Evita que el programa de falsos positivos, en cambios de tensión suaves y progresivos. Por defecto su valor es 10 y corresponde a un tiempo de 10 segundos de adaptación. Esto es últil para evitar falsos positivos en el caso de que la fotoresistencia esté iluminada por luz ambiental, que irá aumentado o disminuyendo según las horas del día.
const long rango=6; // este es el rango por el que se disparará la salida 2 y pasa a estado lógico 1
const long tiempo=1000; // tiempo que permanecerá activa la salida 2 en caso de pasar a estado lógico 1
long sensorValue; // Declaración de la variable que contendrá le lectura de tensión del pin analógico cero, del arduino;
long ultimamedicion; // contiene el valor de la última medición que disparó a lógico 1, la salida 2

void setup() {
 //Serial.begin(9600); // esto es para poder leer por el puerto serie los valores medidos
  pinMode(A0, INPUT); // se establece el pin analógico 0 del arduino como pin de entrada de datos
  pinMode(2, OUTPUT); // se establece el pin digital 2 del arduino como pin de salida de datos
  long sensorValue = analogRead(A0); // este trozo de código, se pone aquí, para evitar que el programa de un falso positivo nada más ponerse en funcionamiento
  ultimamedicion = sensorValue; // este trozo de código, se pone aquí, para evitar que el programa de un falso positivo nada más ponerse en funcionamiento
}

void loop() {
  

 for (int i=0; i <= 1000; i++){ // El bucle FOR sirve para que transcurrido un tiempo de 10 segundos, se asigne automáticamente el valor leído por la fotorresistencia a la variable última medición. Esto se hace para que el programa se adapte gradualmente a los cambios suaves de luz, normales en ambientes de luz natural. Si no se hiciese esto, el detector daría falsos positivos, por la normal caída o aumento de la luz ambiental,motivadas por la hora del día.

  long sensorValue = analogRead(A0); // se asigna a la variable "sensorValue" el valor leído por el pin analógico 0, correspondiente a la tensión leída en la fotorresistencia
  
  if (sensorValue >= ( ultimamedicion+rango)) // La salida 2 pasa a 1 lógico si la tensión medida en la entrada analógica 0 es mayor que la anterior lectura + la tensión de RANGO
  {
    digitalWrite(2, HIGH); // se enciende el LED
    ultimamedicion = sensorValue;
    delay(tiempo); // tiempo que permanece encendido el led
  }
  else  // La salida 2 pasa a 0 si la tensión medida en la entrada analógica 0 no es mayor
  {
  digitalWrite(2, LOW);
  }
  
  
    
  if (sensorValue <= ( ultimamedicion-rango))  // La salida 2 pasa a 1 lógico si la tensión medida en la entrada analógica 0 es menor que la anterior lectura - la tensión de RANGO
  {
    digitalWrite(2, HIGH);      
    ultimamedicion = sensorValue;
    delay(tiempo);
  }
  else
  {
  digitalWrite(2, LOW);
  }
    
 
  delay(tiempoadaptacion); // el tiempo de delay, determina cuanto tiempo en el que el programa se irá adaptando a los cambio suabes de tensión, medidos en la entrada cero del arduino.
}

  // transcurridos 10 segundos, se asigna automáticamente el valor leydo por la fotoresistencia, a la variable "ultimamedicion", para que el programa se adapte a los cambios suaves y progresivos de tensión, producido por los cambios suaves y progresivos de luz y así evitar errores.
  long sensorValue = analogRead(A0);
  ultimamedicion = sensorValue;
 
  //Serial.println(sensorValue); // Por si quieres ver por el puerto serie las lecturas tomadas
  //Serial.println(ultimamedicion); // Por si quieres ver por el puerto serie las lecturas tomadas


}

« Last Edit: June 07, 2012, 10:10:42 am by lm386 » Logged

Pages: [1]   Go Up
Jump to: