User Tools

Site Tools


bh1750

BH1750 Light Sensor

By using a BH1750 the Raspberry Pi can easily measure the intensity of light via I²C. The BH1750 is an digital Ambient Light Sensor IC for I²C bus interface. This IC is the most suitable to obtain the ambient light data for adjusting LCD and Keypad backlight power of mobile phones. It is possible to detect wide range at High resolution. The values are interpreted in Lux from 1 to 65535 Lux.

Installation

Easily install the light sensor to the I²C bus and ensure it's not getting more than 3.3V (except, a voltage reulator is added). No further addon-on are neccessary.

Basic-Test

To ensure it's working as expected, just check the I²C bus of the pi. If the address PIN is connected to ground, the base address is 0x23 (or 0x5C if pulled to Vcc). This can be verified here:

pi@DevPi:~/BH1750 $ sudo i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- 23 -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --

To stat an initial test a simple reading can be done via I²C tools directly from command line. Here are two simple single measure and read commands at 1 lx resolution started. Measurement time is typically 120ms. Right after measurement the sensor is automatically set to Power Down mode again:

pi@DevPi:~/BH1750 $ sudo i2cset -y 1 0x23 0x20
pi@DevPi:~/BH1750 $ sudo i2cget -y 1 0x23 0x00 w
0x7400

pi@DevPi:~/BH1750 $ sudo i2cset -y 1 0x23 0x20
pi@DevPi:~/BH1750 $ sudo i2cget -y 1 0x23 0x00 w
0x7500

Measurement with maximum full light (tested with a laser pointer):

pi@DevPi:~/BH1750 $ sudo i2cset -y 1 0x23 0x20
pi@DevPi:~/BH1750 $ sudo i2cget -y 1 0x23 0x00 w
0xffff

Ensure to remind the “w” to read a complete word from the first value (0x00).

Test-Program in C

Small simple test programm to read every second the light value from the sensor, this requires wiringPi to be installed:

#include <wiringPiI2C.h>
#include <stdio.h>
int main (void) 
{
  int handle = wiringPiI2CSetup(0x23);
  while(1)
  {
    //wiringPiI2CWrite(handle, 0x10); // Continously measurement at 1 lx resolution. Measurement Time is typically 120ms.
    wiringPiI2CWrite(handle, 0x21);   // One-time measurement at 0.5 lx resolution. Measurement Time is typically 120ms. It is automatically set to Power Down mode after measurement.
    sleep(1);
    int word = wiringPiI2CReadReg16(handle, 0x00);
    int lux = ((word & 0xff00)>>8) | ((word & 0x00ff)<<8);
    int percent = (100.0/65535.0)*lux;
    printf("Current light: %d Lux (%d%)\n", lux, percent);
  }
  return 0;
}

If file is named 'bh1750.c' it can be compiled via:

cc bh1750.c -lwiringPi -o bh1750

And then easily run:

./bh1750

The output it creates looks like depending on the light:

Current light: 40374 Lux (61%)
Current light: 19456 Lux (29%)
Current light: 65535 Lux (100%)
Current light: 65535 Lux (100%)
Current light: 848 Lux (1%)
Current light: 1414 Lux (2%)
Current light: 32628 Lux (49%)
Current light: 33013 Lux (50%)
Current light: 33077 Lux (50%)
Current light: 25530 Lux (38%)
Current light: 24693 Lux (37%)
Current light: 15292 Lux (23%)
Current light: 11121 Lux (16%)
Current light: 11150 Lux (17%)
Current light: 10616 Lux (16%)
Current light: 9017 Lux (13%)
Current light: 7368 Lux (11%)
Current light: 6936 Lux (10%)
Current light: 6381 Lux (9%)
Current light: 6577 Lux (10%)
Current light: 7246 Lux (11%)
Current light: 7874 Lux (12%)
Current light: 7903 Lux (12%)
Current light: 8073 Lux (12%)
Current light: 8165 Lux (12%)
Current light: 8114 Lux (12%)
Current light: 8197 Lux (12%)
Current light: 8243 Lux (12%)
Current light: 8241 Lux (12%)
Current light: 14976 Lux (22%)
Current light: 108 Lux (0%)
Current light: 103 Lux (0%)

Test-Program in Python

Small simple test programm to read every second the light value from the sensorusing python:

#!/usr/bin/python
import smbus
import time
 
# Constants taken from the datasheet
 
DEVICE     = 0x23 # Default device I2C address
 
POWER_DOWN = 0x00 # No active state
POWER_ON   = 0x01 # Power on
RESET      = 0x07 # Reset data register value
 
# Start measurement at 4 lx resolution. Time typically 16ms.
CONTINUOUS_LOW_RES_MODE = 0x13
 
# Start measurement at 1 lx resolution. Time typically 120ms
CONTINUOUS_HIGH_RES_MODE_1 = 0x10
 
# Start measurement at 0.5 lx resolution. Time typically 120ms
CONTINUOUS_HIGH_RES_MODE_2 = 0x11
 
# Start measurement at 1 lx resolution. Time typically 120ms
# Device is automatically set to Power Down after measurement.
ONE_TIME_HIGH_RES_MODE_1 = 0x20
 
# Start measurement at 0.5 lx resolution. Time typically 120ms
# Device is automatically set to Power Down after measurement.
ONE_TIME_HIGH_RES_MODE_2 = 0x21
 
# Start measurement at 1 lx resolution. Time typically 120ms
# Device is automatically set to Power Down after measurement.
ONE_TIME_LOW_RES_MODE = 0x23
 
#bus = smbus.SMBus(0) # Rev 1 Pi uses 0
bus = smbus.SMBus(1)  # Rev 2 Pi uses 1
 
def convertToNumber(data):
  # Simple function to convert 2 bytes of data
  # into a decimal number
  return ((data[1] + (256 * data[0])) / 1.2)
 
def readLight(addr=DEVICE):
  data = bus.read_i2c_block_data(addr, ONE_TIME_HIGH_RES_MODE_2)
  return convertToNumber(data)
 
def main():
 
  while True:
    print "Light Level : " + str(readLight()) + " lx"
    time.sleep(1)
 
if __name__=="__main__":
   main()

This creates an output like:

pi@DevPi:~/BH1750 $ python bh1750.py 
Light Level : 190.0 lx
Light Level : 188.333333333 lx
Light Level : 189.166666667 lx
Light Level : 190.833333333 lx
Light Level : 186.666666667 lx
Light Level : 190.833333333 lx
Light Level : 189.166666667 lx
Light Level : 187.5 lx
Light Level : 191.666666667 lx
bh1750.txt · Last modified: 03.01.2017 14:46 by andreas