BH1750. Sensor de luz ambiental con bus I2C.

BH1750. Sensor de luz ambiental con bus I2C.

BH1750. Sensor de luz ambiental con bus I2C.

El BH1750 es un sensor de iluminación ambiental con una resolución y sensibilidad razonablemente altas. Se comporta frente a la luz visible de una forma equiparable a la del ojo humano y no se ve afectado por la radiación infrarroja ni depende de la temperatura de color del tipo de iluminación, es decir, funciona bien con luz natural y con diferentes tipos de iluminación artificial. Se comunica de forma digital con el microcontrolador, con el bus I2C, por lo que es resistente a interferencias si se sitúa a cierta distancia del circuito que lo lee. Su tiempo de respuesta es bastante bajo, menos de 200 ms en las circunstancias más desfavorables.

Tabla de contenidos

    BH1750 Sensor luz ambiental

    Desde el punto de vista electrónico su implementación es muy sencilla. Sólo hay que conectar la alimentación (entre 2,4 V y 3,6 V) y el bus I2C. Opcionalmente puede cambiarse la dirección del bus para conectar dos dispositivos (con ADDR a nivel bajo es 0B0100011 o 0x23 y con ADDR a nivel alto es 0B1011100 o 0x5C) y utilizarse la línea VDI para la función reset con el microcontrolador.

    Para conectar el BH1750 a Arduino, además de alimentarse con la salida de 3,3 V, lo más correcto es usar un conversor de nivel además de con las resistencias pull-up para el bus I2C. Aunque el componente soportará una conexión directa al bus bus I2C no es recomendable dimensionar un circuito sin considerar convertir el nivel.

    Sensor de iluminación ambiental BH1750. Circuito de aplicación

    Por su popularidad, que viene dada por ser muy barato en relación a su precisión, existen varios módulos, como el conocido GY-30, que puede verse en la fotografía del principio. Para conectarlos de manera más cómoda al prototipar con un microcontrolador, suelen incluir conversores de nivel para el bus I2C y reguladores de tensión para alimentarlos con una tensión más alta (hasta 5 V) en lugar de la salida de 3,3 V de Arduino.

    El BH1750 tiene dos modos de lectura, continua e individual, que corresponden con dos estados, activo y de bajo consumo o reposo. Mientras que si se utiliza el modo de lectura continua el BH1750 sigue activo tras el muestreo, después de realizar una medición individual entra automáticamente en el modo de reposo y bajo consumo. La primera lectura del modo continuo tarda a lo sumo 180 ms y las sucesivas entre 16 ms y 120 ms dependiendo de la resolución.

    El sensor es capaz de medir a intervalos (resolución) de 4 lux, 1 lux y 0,5 lux. El BH1750 recomienda en su hoja de datos utilizar la resolución de 1 lux, que permite distinguir iluminaciones por debajo de los 10 lux (que corresponde con la luz crepuscular) y que es más inmune al ruido que podría afectar a la medida.

    Las resoluciones de 1 lux y 4 lux utilizan los 16 bits de datos para representar la parte entera por lo que se puede alcanzar una medida máxima de 65535 lux (día soleado sin luz directa). El modo de 0,5 lux usa el bit menos significativo para la parte decimal (mide de 0,5 lux en 0,5 lux) por lo que con los 15 bits restante se puede conseguir representar un valor máximo de 32767 lux (exterior sin luz directa)

    iluminación solar teórica frente a la capacidad de media del BH1750
    Iluminación solar teórica del lugar y día de escritura del artículo (hora legal, no solar) frente a la capacidad de media del BH1750 a 1 lux

    Normalmente la ventana óptica conforme a la cual se mide la luz ambiental corresponde a todo el espectro visible y se trata de conseguir una distribución de sensibilidad en el mismo equiparable a la humana. Si la ventana óptica se reduce (se mide luz en un rango de longitud de onda menor) se puede aumentar la sensibilidad del BH1750 (hasta 0,11 lux) con un modo de cancelación del ajuste de la influencia de la ventana óptica aumentando el tiempo de lectura en proporción. Como en este modo especial (sobredimensionado) se realizan lecturas separadas, el contexto debe permitirlo sin que se alteren especialmente las condiciones de medida (por ejemplo, el sensor debe permanecer muy estable, no debe moverse hacia una zona con diferentes condiciones de iluminación)

    Códigos de operación del BH1750

    Estado
    5>

    • 0B00000000 (0x00) Modo de bajo consumo o inactividad.

    • 0B00000001 (0x01) Encendido.

    • 0B00000111 (0x07) Reset. Borra los registros de datos del BH1750.

    Resolución
    5>

    • 0B00010011 (0x13) Medida continua a 4 lux de resolución (entre 16 ms y de tiempo de lectura)

    • 0B00010000 (0x10) Medida continua a 1 lux de resolución (120 ms de tiempo de lectura)

    • 0B00010001 (0x11) Medida continua a 0,5 lux de resolución (120 ms de tiempo de lectura)

    • 0B00100011 (0x23) Una medición a 4 lux de resolución (16 ms de tiempo de lectura)

    • 0B00100000 (0x20) Una medición a 1 lux de resolución (120 ms de tiempo de lectura)

    • 0B00100001 (0x21) Una medición a 0,5 lux de resolución (120 ms de tiempo de lectura)

    Ajuste por cambio en la ventana óptica
    5>

    • 0B011MT [0,1,2,3,4] Bit bajo del registro MTREG (Measurement Time REGister).

    • 0B01000MT [5,6,7] Bit alto del registro MTREG.

    Leer el BH1750 desde Arduino

    Para medir la iluminación ambiental con el BH1750 desde Arduino se utiliza la librería Wire que gestiona las comunicaciones con el bus I2C. El proceso es el habitual en este tipo de comunicaciones, en primer lugar se activan (una vez en el programa) con Wire.begin(), se inicia la comunicación con el BH1750 con Wire.beginTransmission() y su dirección I2C (0x5C o 0x23 según ADDR esté a nivel alto o bajo respectivamente), se configura enviando el código correspondiente con Wire.write() y se libera el bus con Wire.endTransmission()

    Si se utiliza uno de los modos de lectura continua, para obtener los datos se utiliza Wire.beginTransmission() con la dirección I2C correspondiente para acceder al BH1750, se le solicitan dos bytes (la resolución es de 16 bits) con Wire.requestFrom() que se leen, usando Wire.read(), y se cargan en un entero sin signo, rotando 8 bits el primer byte. Posteriormente se libera el bus con Wire.endTransmission(). El resultado final se obtiene dividiendo el valor devuelto por el factor de precisión (1,2 si no se cambia la ventana óptica)

    Si se utiliza el modo de lecturas individuales el BH1750 entra en modo de reposo, para volver al modo activo se puede enviar una configuración (el mismo modo de lectura o uno nuevo) o el código de encendido (0x01). Para forzar al BH1750 a entrar en modo de reposo se puede utilizar el código de apagado (0x00).

    Es importante respetar el tiempo de lectura del sensor que depende de la resolución. Si la espera no es crítica, se puede unificar en un valor para todos los casos que puede ser un poco mayor del máximo esperado para asegurarse de que se completa la lectura.

    Para hacer más cómoda la escritura de código para el BH1750 en Arduino, en el siguiente documento de cabecera se encuentran los códigos de operación más relevantes.

    El siguiente código de ejemplo muestra el modo de lectura más habitual en el sensor de luz I2C BH1750. La resolución es de 1 lux y el modo de lectura continua. En el ejemplo se muestra, usando la consola serie de Arduino, cada resultado que se obtiene a partir del valor medido.

    Como decía más arriba, tanto el modo de resolución de 1 lux como el de 4 lux utilizan los 16 bits de datos para expresar la medida como un entero. En cambio, el modo de 0,5 lux el último bit representa una parte decimal, es decir, el valor que aporta al total de la medida está desplazado una potencia de dos a la derecha. En el modo de 1 lux o de 4 lux el último bit (LSB) vale 20, el penúltimo 21, el siguiente 22… en el modo de 0,5 lux el último bit (LSB) vale 2-1, el penúltimo 20, el siguiente 21

    Conforme a esta estructura de datos, y considerando que hay que realizar dos lecturas I2C de un byte, para obtener el valor de 16 bits hay que cargar los bits del byte más significativos, los primeros que se leen, y rotarlos 8 bits a la izquierda en el modo de resolución de 1 lux y en el de 4 lux y solamente 7 bits en el de 0,5 lux. Para unificar la forma de lectura en el modo de 0,5 lux se puede cargar el byte más significativo en un entero sin signo, rotar 8 bits a la izquierda, cargar el byte menos significativo y rotar todo el entero sin signo 1 bit a la derecha, preservando el valor de la parte decimal que indica el LSB (bit menos significativo) para aplicarlo después.

    Lógicamentem para los modos de 1 lux o de 4 lux es necesario utilizar enteros sin signo (unsigned int) para que Arduino no reserve el MSB (bit más significativo) para el signo y poder operar directamente con el valor verdadero de la medida, no con un número negativo. En Arduino Due no es necesario ya que los enteros utilizan 32 bits, pero el mismo programa también funcionará si se utiliza también unsigned int.

    El siguiente código muestra cómo se utilizaría el modo de 0,5 lux

    Descargar los documentos de los ejemplos de medida de la luz ambiental con el sensor BH1750 y Arduino.

    Publicar comentario

    Puede que te hayas perdido