medir-cantidad-de-luxes-con-arduino-y-el-luxometro-bh1750

Medir cantidad de luxes con Arduino y el luxómetro BH1750

El BH1750 es un sensor digital del nivel de luz que puede ser conectado con facilidad a un autómata o procesador como Arduino para formar un luxómetro.

A diferencia a otros sistemas de medición del nivel de luz, como por ejemplo las resistencias LDR, la respuesta espectral del BH1750 está diseñada para ser similar a la del ojo humano por lo que son capaces de proporcionar la medición de lux.

Recordamos que los luxes son la unidad del sistema internacional para la iluminancia. La iluminancia es la relación entre el flujo luminoso (la cantidad de luz emitida por una fuente de luz, y la superficie en la que se mide.

A modo de referencia, para que tengáis un orden de magnitud de luxes, algunos ejemplos típicos de iluminancia.

SituaciónLuxes
Noche0.001-0.02
Luna llena0.2-0.6
Día nublado, en interior5-50
Día nublado, en exterior50-500
Día soleado, en interior100-1000
Bajo luz directa del sol100.000
Habitación, salón150-300
Mesa oficina/lectura500-700
Supermercados/exposiciones750-1000
Mesas dibujo/trabajo1000-1500

El BH1750 tiene un amplio rango de medición ajustable desde los 0.11 a 100000 lux, por lo que es capaz de medir en casi cualquier situación de iluminación. Incorpora un ADC de 16bits que proporciona una resolución de 65535 niveles.

El sensor BH1750 tiene una baja influencia al espectro infrarrojo, rechazo al ruido de 50/60 Hz (luz artificial) y alta independencia del origen de la fuente de luz (luz natural, halógenos, LED, incandescencia).

arduino-luxometro-bh1750-interior

La comunicación se realiza a través del bus I2C, por lo que es sencillo obtener los datos medidos. La tensión de alimentación es de bajo voltaje entre 2.4 a 3.6V.

Frecuentemente se encuentran integrados en módulos que incorporan la electrónica necesaria para conectarla de forma sencilla a un Arduino. En la mayoría de los módulos, esto incluye un regulador de voltaje que permite alimentar directamente a 5V.

El BH1750 se emplea, principalmente, para regular la retroiluminación de LCDs y Keypads en dispositivos móviles, así como para regular la iluminación en cámaras digitales.

Nosotros podemos usarlo en nuestros proyectos, por ejemplo, para crear un luxómetro de bajo coste, controlar el funcionamiento de persianas o toldos en domótica o para regular un sistema de iluminación.

Precio

El BH1750 es un sensor muy barato. Podemos encontrar módulos con este luxómetro por 0.85€, buscando en vendedores internacionales de eBay y AliExpress.

arduino-luxometro-bh1750-componente

Esquema de montaje

La conexión es sencilla, simplemente alimentamos el módulo desde Arduino mediante GND y 5V y conectamos el pin SDA y SCL de Arduino con los pines correspondientes del sensor.

arduino-luxometro-bh1750-esquema

Mientras que la conexión vista desde el lado de Arduino quedaría así.

arduino-luxometro-bh1750-conexion

En Arduino Uno, Nano y Mini Pro, SDA es el pin A4 y el SCK el pin A5. Para otros modelos de Arduino consultar el esquema patillaje correspondiente.

Verificar que vuestra placa es compatible con 5V antes de conectarla a Arduino. Si no, tendréis que usar un adaptador de nivel lógico.

Ejemplos de código

Para realizar la lectura del BH1750 usaremos la librería desarrollada por Christopher Laws, disponible en este enlace.

La librería proporciona ejemplos de código, que resulta aconsejable revisar. Los siguientes ejemplos son modificaciones a partir de los disponibles en la librería

El sensor dispone de 3 modos de resolución, siendo el predeterminado el modo “High Resolution Mode”.

ModoResoluciónTiempo de medición
High resolution Mode20.5 lx120 ms
High Resolution Mode1 lx120 ms
Low Resolution Mode4 lux16 ms

Adicionalmente existen 2 modos de disparo, “Continuo” y “One Time”. En el modo continuo el BH1750 realiza constantemente mediciones mientras que en el modo disparo único realiza la medición bajo demanda, pasando a modo baja energía entre solicitudes.

Mostrar nivel de lux

En este ejemplo empleamos el BH1750 para obtener el nivel de iluminancia y, a continuación, mostramos la cantidad de lux por puerto serie.

#include <Wire.h>
#include <BH1750.h>

BH1750 luxometro;

const byte luxMode = BH1750_CONTINUOUS_HIGH_RES_MODE;
// BH1750_CONTINUOUS_HIGH_RES_MODE
// BH1750_CONTINUOUS_HIGH_RES_MODE_2
// BH1750_CONTINUOUS_LOW_RES_MODE
// BH1750_ONE_TIME_HIGH_RES_MODE
// BH1750_ONE_TIME_HIGH_RES_MODE_2
// BH1750_ONE_TIME_LOW_RES_MODE

void setup() {
  Serial.begin(9600);
  Serial.println(F("Inicializando sensor..."));
  luxometro.begin(luxMode); // Inicializar BH1750
}

void loop() {
  uint16_t lux = luxometro.readLightLevel(); // Lectura del BH1750
  Serial.print(F("Iluminancia:  "));
  Serial.print(lux);
  Serial.println(" lx");
  delay(500);
}

Encender un dispositivo con el luxómetro

En este ejemplo empleamos la lectura del nivel de iluminación junto con dos umbrales superior e inferior para encender y apagar un dispositivo.

En el ejemplo empleamos el LED integrado en la placa para verificar el funcionamiento, por ejemplo, tapando el BH1750 con la mano y comprobando que el LED se apaga y enciende correctamente.

No obstante, en un ejemplo real emplearíamos la salida digital para realizar una acción como desplegar un toldo o cerrar una persiana, para lo que podemos emplear transistores BJT, transistores MOSFET o salidas por rele.

#include <Wire.h>
#include <BH1750.h>

BH1750 luxometro;;
const byte luxMode = BH1750_CONTINUOUS_HIGH_RES_MODE;

const uint16_t lowThreshold = 20;
const uint16_t highThreshold = 50;

const int pinOut = LED_BUILTIN;

void setup() {
  Serial.begin(9600);
  Serial.println(F("Inicializando sensor..."));
  luxometro.begin(luxMode); // Iniciar BH1750
}

void setup() {
  Serial.begin(9600);
  Serial.println(F("Inicializando sensor..."));
  luxometro.begin(BH1750_CONTINUOUS_HIGH_RES_MODE); // Iniciar sens el sensor
  pinMode(pinOut, OUTPUT);
  digitalWrite(pinOut, LOW);
}

void loop() {
  uint16_t lux = luxometro.readLightLevel();  // Lectura iluminancia
  
  if (lux < lowThreshold)
  {
    digitalWrite(pinOut, HIGH);
  }
  else if (lux > highThreshold)
  {
    digitalWrite(pinOut, LOW);
  }
  delay(500);
}

Descarga el código

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