medir-nivel-luz-con-arduino-y-fotoresistencia-ldr

Medir nivel de luz con Arduino y fotoresistencia LDR (GL55)

En esta entrada aprenderemos a medir el nivel de luz, tanto en interiores o exteriores, con la ayuda de Arduino y una fotoresistencia LDR (familia GL55 o similar), usando las entradas analógicas de Arduino.

¿Qué es un fotoresistor LDR?

Un fotoresistor, o LDR (light-dependent resistor) es un dispositivo cuya resistencia varia en función de la luz recibida. Podemos usar esta variación para medir, a través de las entradas analógicas, una estimación del nivel del luz.

Un fotoresistor está formado por un semiconductor, típicamente sulfuro de cadmio CdS. Al incidir la luz sobre él algunos de los fotones son absorbidos, provocando que electrones pasen a la banda de conducción y, por tanto, disminuyendo la resistencia del componente.

Por tanto, un fotoresistor disminuye su resistencia a medida que aumenta la luz sobre él. Los valores típicos son de 1 MOhm en total oscuridad, a 50-100 Ohm bajo luz brillante.

Por otro lado, la variación de la resistencia es relativamente lenta, de 20 a 100 ms en función del modelo. Esta lentitud hace que no sea posible registrar variaciones rápidas, como las producidas en fuentes de luz artificiales alimentadas por corriente alterna. Este comportamiento puede ser beneficioso, ya que dota al sensor de una gran estabilidad.

Finalmente, los fotoresistores no resultan adecuados para proporcionar una medición de la iluminancia, es decir, para servir como luxómetro Esto es debido a su baja precisión, su fuerte dependencia con la temperatura y, especialmente, a que su distribución espectral no resulta adecuada para la medición de iluminancia.

ldr-graficas

Por tanto, un LDR es una sensor que resulta adecuado para proporcionar medidas cuantitativas sobre el nivel de luz, tanto en interiores como en exteriores, y reaccionar, por ejemplo, encendiendo una luz, subiendo una persiana, u orientando un robot.

Para medir la cantidad de luxes con Arduino necesitaréis un luxómetro como el BH1750 como vemos en la entrada Medir cantidad de luxes con Arduino y el luxómetro BH1750

Precio

Las fotoresistencias son dispositivos realmente baratos. Podemos encontrar 20 sensores LDR por 1€ en vendedores internacionales en Ebay, gastos de envío incluidos.

ldr-gl55

¿Cómo funciona un fotoresistor LDR?

Matemáticamente, la relación entre la iluminancia y la resistencia de una LDR sigue una función potencial.

Siendo R0 la resistencia a una intensidad I0, ambas conocidas.

La constante gamma es la pendiente de la gráfica logarítmica, o la pérdida de resistencia por década. Su valor típicamente 0.5 a 0.8.

Por este motivo, frecuentemente las gráficas que relacionan ambos valores se representan en escalas logarítmicas para ambos ejes. Bajo esta representación, la relación se muestra como una gráfica lineal.

ldr-resistencia

Estos valores pueden ser obtenidos del datasheet del componente. Por ejemplo, para la familia GL55 de fotoresistores son los siguientes:

ModeloPico
espectral
(nm)
Resistencia
luz brillante
(KΩ)
Resistencia
oscuridad
(KΩ)
gammaTiempo
respuesta
(ms)
GL55165405-105000.530
GL552854010-2010000.625
GL5537-154020-3020000.625
GL5537-254030-5030000.725
GL553954050-10050000.825
GL5549540100-200100000.925

Sin embargo, siempre existirán pequeñas variaciones entre dispositivos, incluso dentro de la misma familia, debidos a la fabricación del componente.

El comportamiento potencial hace que estas pequeñas diferencias supongan grandes variaciones en la medición, por lo que no es posible, en general, emplear estos valores de forma absoluta sin un proceso de calibración.

Esquema eléctrico

El esquema eléctrico sería el siguiente.

arduino-ldr-esquema

Montaje

Por su parte, el montaje eléctrico en una protoboard quedaría de la siguiente manera.

arduino-ldr-montaje

Ejemplos de código

A continuación tenéis algunos ejemplos de código. En el siguiente, usamos las entradas digitales para hacer parpadear el LED integrado en la placa mientras el LDR recibe luz suficiente.

const int LEDPin = 13;
const int LDRPin = 2;

void setup()
{
pinMode(LEDPin, OUTPUT); 
pinMode(LDRPin, INPUT);
} 

void loop()
{
  int value = digitalRead(LDRPin);
  if (value == HIGH)
  {
    digitalWrite(LEDPin, HIGH);
    delay(50);
    digitalWrite(LEDPin, LOW);
    delay(50);
  }
}

El siguiente ejemplo emplea una entrada analógica para activar el LED integrado en la placa si supera un cierto umbral (threshold).


const int LEDPin = 13;
const int LDRPin = A0;
const int threshold = 100;

void setup() {
  pinMode(LEDPin, OUTPUT);
  pinMode(LDRPin, INPUT);
}

void loop() {
  int input = analogRead(LDRPin);
  if (input > threshold) {
    digitalWrite(LEDPin, HIGH);
  }
  else {
    digitalWrite(LEDPin, LOW);
  }
}

El siguiente código proporciona una lectura del nivel de iluminación recibido. Observar que los cálculos se realizan con aritmética de enteros, evitando emplear números de coma flotante, dado que ralentizan mucho la ejecución del código.

const long A = 1000;     //Resistencia en oscuridad en KΩ
const int B = 15;        //Resistencia a la luz (10 Lux) en KΩ
const int Rc = 10;       //Resistencia calibracion en KΩ
const int LDRPin = A0;   //Pin del LDR

int V;
int ilum;

void setup() 
{
   Serial.begin(115200);
}

void loop()
{
   V = analogRead(LDRPin);         

   //ilum = ((long)(1024-V)*A*10)/((long)B*Rc*V);  //usar si LDR entre GND y A0 
   ilum = ((long)V*A*10)/((long)B*Rc*(1024-V));    //usar si LDR entre A0 y Vcc (como en el esquema anterior)
  
   Serial.println(ilum);  
   delay(1000);
}

Descarga el código

Todo el código de esta entrada está disponible para su descarga en Github. github-full