domingo, 18 de enero de 2015

Ajuste luminosidad de un LED con LDR

Hola a todos. En esta entrada vamos a seguir  trabajando con las LDR.

Hay un tipo de montaje muy común con fotorresistencias que  varía la luminosidad de un LED en función de la  luz que incide en el LDR. Es fácil encontrarlo pero vamos a desarrollarlo para introducir nuevos conceptos y como base para otras entradas posteriores.

El enunciado por tanto, de lo que queremos conseguir, es el siguiente. Queremos un circuito que varíe la luminosidad de un LED en función de la cantidad de luz incidente en el LDR.

A primera vista el planteamiento debería ser prácticamente un “copy-paste” de la entrada sobre PWM, (puedes consultarla aquí), pero cambiando el potenciómetro por el LDR. El esquema es el mismo expuesto en la entrada anterior:


Por lo tanto no variará el montaje, es éste:


La diferencia la tendremos en el rango dinámico que encontraremos en la entrada analógica. Con el potenciómetro, conectado como divisor de tensión, la entrada podía oscilar entre los 0 y los 5V, o en digital entre valores comprendidos entre 0 y 1023.

Con el circuito propuesto, la entrada nunca podrá alcanzar los 5V, pues con la mayor de las fuentes de luz incidiendo en el LDR, tendría una resistencia de más de 100Ω, por tanto la entrada del Arduino vería una tensión de:

I=V/(R+LDR)=5/10.100=0.495mA

VARD=R*I=10.000*0.000495=4,95V

Insisto en que este valor con una fuente de luz muy intensa y muy próxima al LDR.

Para calcular elvalor mínimo de tensión, a oscuras, debemos contemplar una resistencia del LDR de 0.5MΩ. Calculando ota vez la corriente que fluye por la malla:

I=V/(R+LDR)=5/510000=0.0098mA

VARD=R*I=10.000*0.0000098=0.098V

Estos serían valores comprendidos entre máximos y mínimos, que están muy lejos de condiciones reales de funcionamiento.

En condiciones normales yo he obtenido diferencias de unos 3 Voltios, lo que traducido al conversor AD del Arduino (entrega valores entre 0 y 1023), nos da una resolución de tan solo 600 puntos de los 1024 posibles.

Veamos primero como funcionaría una adaptación simple del sketch empleado en el ejemplo del potenciómetro.

int lightPin = 0;  //define el pin de la foto-resistencia
int ledPin=9;     //define el pin para el  LED
int valor;     //define una variable en la que haremos los cálculos

void setup()
{
    Serial.begin(9600);  //Inicializa la comunicación serie
    pinMode( ledPin, OUTPUT );
}

void loop()
{
    valor = analogRead(lightPin);
    analogWrite(ledPin, valor); 
    Serial.println(valor); 
    delay(1000); //pequeño retardo para darle
               // tiempo al LED a responder.
}


¿Qué sucede cuando lo cargamos en el Arduino? 
Antes de nada abrir el serial monitor, y probad a tapad y destapar el LDR y observar los valores obtenidos.  Os muestro los obtenidos en mi caso:





Si vemos los valores obtenidos en la entrada,podemos observar que están entre los 238 y los 774. Eso es debido a que como he comentado anteriormente, en condiciones normales nunca se alcanzan los valores extremos, 0 y 1023. Veamos como solucionar este apartado, para que trabaje solamente entre los valores “ de campo” y el LED pase por todos los estados posibles, incluido el apagado o máximo brillo.

Nota: estos valores son para mis componentes y en las condiciones de casa. Aunque para cada caso variará, no alcanzará los valores extremos.

Map y constrain


Necesitamos hacer proporcional la salida a los valores de entrada, convirtiendo el valor mínimo en la entrada del Arduino, en el "0" de la salida, y el valor máximo obtenido en la entrada en el "255", valor máximo en la salida.

Ya existe una función que rescala estos valores, es la función map. Esta función usa los siguientes argumentos:

map ( valor, fromLow, fromHigh, toLow, toHigh )

Una breve descripción de los parámetros sería:

valor:        número que queremos reescalar,
fromLow: límite inferior de la horquilla que queremos usar como valores de entrada,
fromHigh: este es el límite superior a usar en los valores de entrada,
toLow:      valor mínimo a obtener en la salida,
toHigh:     valor máximo  a obtener en la salida.


Los valores toLow y toHigh, serán los valores mínimo y máximo de la salida PWM, 0 y 255.

Los valores de entrada fromLow y fromHigh, en esta entrada los hallaremos de forma empírica.

Los pasos a seguir, serían los siguiente:

- Cargar el sketch,
- Lanzar el monitor serial,
- Someter el LDR a la fuente de luz mínima y máxima y anotar lo valores obtenidos,
- Modificar el sketch con los valores máximo y mínimos y volverlos a cargar

El sketch est aquí:


/* Ejemplo para reescalr los valores obtenidos en la entrada 
analogica del Arduino. En este caso usamos un LDR conectado a A0,
a traves de un divisor de tension con un a resistencia de 10.000ohmios*/

int lightPin = 0; // Pin LDR.
int ledPin = 9; // Pin LED.
int valor; // Variable para cálculos.
int ajuste;
int min = 0; // Valor minimo obtenido por A0.
int max = 1024; // Valor maximo obtenido por A0.

void setup(){

Serial.begin(9600); // Inicializa el puerto serie.
pinMode( ledPin, OUTPUT ); // ledPin como salida.
}

void loop()
{

valor = analogRead(lightPin); // Leemos el valor de A0.
Serial.print ("Valor de entrada: ");
Serial.println(valor); // Valor de entrada de A0.
valor = constrain(valor, min, max); // Normalizamos el valor.
valor = map(valor, min, max, 0, 255); // Re-mapeamos.
analogWrite(ledPin, valor); // Escribimos el valor.


delay(1000); 

}


Vale, casi se me olvidaba. Nos faltaba explicar la función constrain. Esta función restringe los valores de salida a los que queden dentro de la horquilla de valores que hayamos definido. La sintaxis es la siguiente:

constrain (x, a, b)

Siendo :

x: el dato que hemos obtenido,
a: el límite inferior,
b: límite superior,

¿ Cómo funciona?, esta función devuelve:
  • El mismo valor x a la entrada si a < x < b.
  • Si el valor x es menor que o igual a  a, devolverá a,
  • Si es mayor o igual que b, devolverá b.
Esto nos sirve para que el Arduino no tenga en cuenta los valores de fuera del rango que hemos definido en la función map. Los valores por encima o por debajo de los límites se ajustarán a los valores establecidos.

Un video explicativo del procedimiento a seguir.




Bibliografía:

En esta entrada se han usado ejemplos adaptados de la web http://arduino.cc, para explicar las funciones map y constrain.




No hay comentarios:

Publicar un comentario