Tutorial de Arduino en Español – Parte 9 – Fotorresistencia LDR o Sensor crepuscular

La fotorresistencia LDR, es una resistencia que varia su conductividad con la luz, debido a un químico que este lleva en la parte superior, aumentando o reduciendo la conductividad.

Con él podemos medir la cantidad de luz que hay que hay en el entorno, permitiéndonos poder actuar en consecuencia de la luz que haya, lo que se conoce como interruptor crepuscular.

Esquema de conexionado

Esquema de conexionado de la Fotorresistencia LDR con LCD 2004A

En el esquema de conexionado tenemos 2 componentes.

La Fotoresistencia LDR (1) que va a conectado a Arduino en el pin A0 (cable rojo) y el otro a GND a través de un divisor de tensión con una resistencia de 10K Ohm. El orden de los cables da igual, al tratarse de una resistencia el LDR.

Opcionalmente, he conectado una pantalla LCD 2004 al Arduino, para poder visualizar rápidamente la información del sensor HC-SR04. Si quieres saber más acerca del LCD 2004A, hablamos de ella en otro artículo.

Código de Arduino (primer programa)

#include <LiquidCrystal_I2C.h>

int ldr = A0;

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

void setup() {
  // put your setup code here, to run once:
   lcd.begin(20,4);
  lcd.backlight(); 
}

void loop() {
  // put your main code here, to run repeatedly:
  // 0-1024 / 0-256
  int res = analogRead(ldr);
  lcd.setCursor(0,0);
  lcd.print("Luz: ");
  lcd.print(res);
  
  int dig = String(res).length();
  
  for(int i = dig; i < 4; i++)
    lcd.print(" ");
    
  lcd.setCursor(0,1);
  // ANALOGREAD 0-1024
  // 0-256
  if(res >= 300)
      lcd.print("Esta oscuro");
  else
      lcd.print("Hay luz");
  for(int i = 0; i < 4; i++)
    lcd.print(" ");    
    delay(200);
}

Para empezar, importamos y configuramos el LCD 2004A, como paso opcional en caso de que la uséis. Así mismo el pin A0 que es donde conectaremos nuestra resistencia LDR, ya que su valor es analógico y por lo tanto, usamos los pines enumerados con una A delante. En mi caso, definimos la variable con dicho valor para poder usarlo de manera mas fácil en el código.

En el Setup no es necesario introducir codigo, simplemente inicializo mi LCD para poder usarla en el Loop. Ahora si tenemos que escribir código, que es muy sencillo ya que lo único que hay que hacer, es leer valor analógico, en el que yo lo guardaré en la variable res, como podemos observar en la línea int res = analogRead(ldr), siendo ldr la variable anteriormente mencionada donde defino cual es el pin de Arduino donde estará conectado.

En la linea if(res >= 300) comprobamos si el valor devuelto es igual o mayor a 300, recordando que los valores analógicos varían de 0 a 1024 en Arduino UNO/MEGA, y mostramos en el LCD un mensaje diciendo que está oscuro, en caso contrarió, hay luz. Esto es debido a que el valor de resistencia aumenta con la luz, dificultando el paso de la corriente eléctrica, y eso hace que a mas luz, menor será el valor que vamos a leer.

A partir de 300, ya consideramos que la cantidad de luz que hay puede ser insuficiente, por lo tanto, podemos realizar una acción como encender una luz, la cual veremos a continuación.

Código de Arduino (segundo programa)

#include <LiquidCrystal_I2C.h>

bool blink = false;
int ldr = A0;
int led = 11;
int umbral = 400;
bool lightOn = false;
int prevState = 0;
int lightTimer = 0;

// Constructor de la librería de LCD 16x2
// Aqui se configuran los pines asignados a la pantalla del PCF8574
// Este constructor es para usar con el modulo I2C que se muestra en las
// fotografias de nuestro sitio web. Para otros modelos, puede ser necesario
// cambiar los valores de acuerdo al esquemático del adaptador I2C. Los pines
// del arduino SIEMPRE son los correspondientes al I2C (SDA y SCL)
 
// Constructor sin control de backlight (retroiluminacion)
//LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7);
// Constructor con control de backlignt (retroiluminacion)
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

void setup() {
  // put your setup code here, to run once:
  lcd.begin(20,4);
  lcd.backlight();

  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  lcd.setCursor(0,0);
  lcd.print("Luz: ");
  int res = analogRead(ldr);
  lcd.print(res);
  lcd.setCursor(0,2);

  if(res >= 500)
  {
    lcd.print("Luces activadas - ");
    if(!lightOn)
    {
      lightOn = true;
      lightTimer = 0;
    }
  }
  else
  {
    lcd.print("                  ");
    if(lightOn)
    {
      lightOn = false;
      lightTimer = 14;
    }
  }


  if(lightOn && lightTimer < 14)
    lightTimer = lightTimer + 2;
  else if(!lightOn && lightTimer > 0 )
    lightTimer--;
    

  if(lightTimer == 14)
    analogWrite(led, 150);
    
  else if(lightTimer == 0)

    analogWrite(led, 0); 
     
  prevState = lightOn;

  delay(300);
}

En este segundo código, vamos a encender o apagar un led dependiendo de las condiciones luminicas usando el LDR. Aun que usemos un LED, podemos utilizar cualquier cosa, como por ejemplo un relé que encienda una tira led, por ejemplo.

Para ello vamos a declarar todo lo que necesitemos (en mi caso, también lo relacionado con la LCD2004A).

Creo la variable ldr con valor A0 que será el pin de Arduino donde estará conectado el LDR, la variable led con valor 11, que será el pin de Arduino donde estará mi LED, y la variable umbral con valor 400 que indicará cual es el valor que deberá alcanzar el ldr para que encendamos el LED.

Adicionalmente, creamos la variables que nos permitirán transicionar la iluminación.

En lightOn, guardare si debe estar encendido o no led LED, ya que cuando el LDR de el valor del umbral, no vamos a encender el LED inmediatamentem esperaremos un poco.

Y ya para terminar, lightTimer, que será un temporizador que nos permitirá crear un retardo entre el encendido y el apagado del LED, y así evitar el fenómeno de que se encienda y se apague constantemente cuando el valor del LDR ese en el umbral.

Nuevamente, en la linea int res = analogRead(ldr), leemos el valor de la fotoresistencia LDR para saber cual es el estado de la luz.

En el bloque de código de color azul, tenemos la lógica que comprueba si el valor del LDR esta en el valor del umbral o por encima, y en caso afirmativo, asignamos el valor true a lightOn para que la segunda parte de este código, encienda la luz led, o por el contrario, esta por debajo del umbral, se debe apagar.

En el bloque de código de color rojo, controlamos el temporizador que encenderá o apagará las luces. Para ello, en cada ejecución del loop, se comprueba la variable lightOn la cual si esta en true, empezará a sumar de 2 en 2 hasta llegar a 14, pero si lightOn es false, entonces restará de uno en uno hasta llegar a 0.

En el bloque de código de color verde es donde encendemos o apagamos el LED, teniendo en cuenta la variable temporizador lightTimer. Básicamente lo que hacemos es esperar a que llegue a 14 para encender el LED o a 0 para apagarlo.

De esta manera hacemos ese retardo que comentamos al principio. Esto es útil, por ejemplo, en un vehículo que esta circulando. Durante el día puede pasar que entres en un túnel y por lo tanto, al estar oscuro deba encenderse las luces y al salir apagarse. Pero por ejemplo, si pasas por debajo de la sombra de un árbol, durante un breve periodo de tiempo, hay oscuridad, pero no es real ya que en realidad hay luz.

Con este sistema podemos hacerlo, ya que al tener que llegar la variable lightTimer a 14 mientras lightOn esta encendida, si rápidamente entramos en sombra y salimos, lightTimer no llegará a 14 y volverá a 0 al estar llightOn en false y por lo tanto, las luces no se encenderán.

El caso contrario también funciona, estamos de noche circulando y tenemos las luces encendidas. Al pasar por delante de una farola, durante un instante tenemos luz, y cuando nos alejamos no. Entonces, lightTimer no le dará tiempo a llegar a 0 y por lo tanto, las luces no se apagarán.

Código de ejemplo y videotutorial

Podéis descargar el codigo de ejemplo aqui: http://www.mediafire.com/file/j5kksv7lhxe0gt6/file y el ejemplo práctico con un LED aqui: http://www.mediafire.com/file/g8t07fyx0h2c3yf/file

Deja un comentario