Introduction: BH1750 Digital Light Sensor

Picture of BH1750 Digital Light Sensor

BH1750FVI Is a Digital Light sensor , which is an digital Ambient Light Sensor IC for I2C bus interface. This IC is the most suitable to obtain the ambient light data for adjusting LCD and Keypad backlight power of Mobile phone. It is possible to detect wide range at High resolution.( 1 - 65535 lx ).

this sensor has some advantages such like :

1) Illuminance to Digital Converter
2) Wide range and High resolution. ( 1 - 65535 lx )
3) Low Current by power down function
4) 50Hz / 60Hz Light noise reject-function
5) I2C bus Interface ( f / s Mode Support )
6) No need any external parts
7) It is possible to select 2 type of I2C slave-address.
8) It is possible to detect min. 0.11 lx, max. 100000 lx by using this function.

DataSheet for this sensor will be found here 

it's easy to use and connect , so Let's started

We will need :

1) Arduino Board" Uno,Nano,mini .. "

2)BH1750 Breakout .

3)Solderless Jumper

4)CD4050 Hex Buffer IC , Or 510 Ohm resistor *3

5)BreadBoard .

Step 1: Definition of Luminous ,Lumen

Picture of Definition of Luminous ,Lumen

illuminance is a measure of how much luminous flux is spread over a given area. One can think of luminous flux (measured in lumens) as a measure of the total "amount" of visible light present, and the illuminance as a measure of the intensity of illumination on a surface 

Lumen : The unit for the quantity of light flowing from a source in any one second (the luminous power, or luminous flux) is called the lumen.


In our sensor we will take a reading from it in Lux which is equal  to one lumen per square metre:

Lux = 1 Lm/m2 .


Step 2: Datasheet .....inside

Picture of Datasheet .....inside

The DataSheet  for BH1750 has a specification of :

Supply voltage : prefer to use 3.3 V to communicate with , Not 5V TTL Logic 

I2C Protocol is used to communicate with Microcontroller , with clock SCL Frequency 400KHz .

Measurement mode: this sensor has 3 Measurement mode :

1) H-resolution with Sensitivity 0.5 lux
2) H-Resolution with Sensitivity 1 lux.
3) L-Resolution with Sensitivity 4 lux.

the datasheet recommended  to use H-Resolution Mode due to kind of noise( including in 50Hz / 60Hz
noise ) is rejected. And H-Resolution Mode is 1 l x resolution so that it is suitable for darkness ( less than 10 lx )

the Instruction Set Architect table show all commend you will need to write a code .

Step 3: Connection

Picture of Connection

as I mentioned before , the BH1750FVI  breakout works with 3.3V , Not with 5V  so You can connect this breakout By using :

510 Ohm Resistor , the input voltage on arduino SDA,SCL Pin not greater 3.6V , tested on oscillscope

using CD4050 Hex Buffer 5-3.3 logic converter .

in Newest  Arduino Board "Like Arduino Uno R3" Has I/OREF Pin above reset Pin , his pin on the Arduino board provides the voltage reference with which the microcontroller operates. A properly configured shield can read the IOREF pin voltage and select the appropriate power source or enable voltage translators on the outputs for working with the 5V or 3.3V.  very nice you can use it .

about ADDR Pin , I prepare a Library " I will talk about in the next step " , You can select the address of your breakout , Even 0x23 , or 0X5C , this action depend on the ADDR Pin status , if connecting to Gnd , the address will be 0x23 , else if ADDR Connecting to Vcc The address will be 0X5C  .


Step 4: Arduino Code

Picture of Arduino Code

I prepared a library for this sensor , You can download it from Here

First Many thanks for Claws , He created a library for BH1750 , You can check it Out .

I prepared a library for it , Tried to solve some issue such like :

1) multi device connecting , You can connect 2 devices of BH1750 WIth different addresses , Depend on ADDR Pin status .

 If ADDR = LOW , The address will be 0x23

If ADDR = HIGH, The address will be 0x5C

2)Power down mode , you can put your sensor in power save mode so it's consume 0.01uA  .

You can downLoad the library from Github , Unzip the attachment and put it in Libraries folder in arduino Path , then restart the arduino IDE .

You can Open the sketch comes with this library .

First program : Read the Lux value via serial Port .

code :

/*
  This is a simple code to test BH1750FVI Light senosr
  communicate using I2C Protocol
  this library enable 2 slave device address
  Main address  0x23
  secondary address 0x5C
  connect this sensor as following :
  VCC >>> 3.3V
  SDA >>> A4
  SCL >>> A5
  addr >> A3
  Gnd >>>Gnd

  Written By : Mohannad Rawashdeh
 
*/

// First define the library :

#include <BH1750FVI.h> // Sensor Library
#include <Wire.h> // I2C Library

BH1750FVI LightSensor;


void setup() {   // put your setup code here, to run once:
   Serial.begin(9600);
  LightSensor.begin();
  /*
Set the address for this sensor
you can use 2 different address
Device_Address_H "0x5C"
Device_Address_L "0x23"
you must connect Addr pin to A3 .
*/
  LightSensor.SetAddress(Device_Address_H);//Address 0x5C
// To adjust the slave on other address , uncomment this line
// lightMeter.SetAddress(Device_Address_L); //Address 0x5C
//-----------------------------------------------
  /*
   set the Working Mode for this sensor
   Select the following Mode:
    Continuous_H_resolution_Mode
    Continuous_H_resolution_Mode2
    Continuous_L_resolution_Mode
    OneTime_H_resolution_Mode
    OneTime_H_resolution_Mode2
    OneTime_L_resolution_Mode
   
    The data sheet recommanded To use Continuous_H_resolution_Mode
  */

  LightSensor.SetMode(Continuous_H_resolution_Mode);
 
  Serial.println("Running...");
}


void loop() {
  // put your main code here, to run repeatedly:
  uint16_t lux = LightSensor.GetLightIntensity();// Get Lux value
  Serial.print("Light: ");
  Serial.print(lux);
  Serial.println(" lux");
  delay(1000);
}

Step 5: LED , LCD 1602 and BH1750

Picture of LED , LCD 1602 and BH1750
On the library attachment You can find Led _BH1750 Code , connect a LED with resistor 100 ohm to pin D9 , The brightness will change inversely with intensity value .

code :

/*
  This is a simple code to test BH1750FVI Light senosr
  communicate using I2C Protocol
  this library enable 2 slave device address
  Main address  0x23
  secondary address 0x5C
  connect this sensor as following :
  VCC >>> 3.3V
  SDA >>> A4
  SCL >>> A5
  addr >> A3
  Gnd >>>Gnd

  Written By : Mohannad Rawashdeh
 
*/

// First define the library :
#include <BH1750FVI.h> // Sensor Library
#include <Wire.h> // I2C Library

uint16_t Light_Intensity=0;
// Call the function
#define LedPin 9 // led connecting to pin D9
BH1750FVI LightSensor;

int SensorValue =0;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
//  call begin Function so turn the sensor On .
  LightSensor.begin();
/*
Set the address for this sensor
you can use 2 different address
Device_Address_H "0x5C"
Device_Address_L "0x23"
you must connect Addr pin to A3 .
*/
  LightSensor.SetAddress(Device_Address_H); //Address 0x5C
// To adjust the slave on other address , uncomment this line
// lightMeter.SetAddress(Device_Address_L); //Address 0x5C
//-----------------------------------------------
   /*
   set the Working Mode for this sensor
   Select the following Mode:
    Continuous_H_resolution_Mode
    Continuous_H_resolution_Mode2
    Continuous_L_resolution_Mode
    OneTime_H_resolution_Mode
    OneTime_H_resolution_Mode2
    OneTime_L_resolution_Mode
   
    The data sheet recommanded To use Continuous_H_resolution_Mode
  */
  LightSensor.SetMode(Continuous_H_resolution_Mode);
  pinMode(9,OUTPUT) // Connect LED With 100ohm resistor
  // to pin D9
 
 
}

void loop() {
  // put your main code here, to run repeatedly:
  // call GetLightIntensity() Function , so the sensor read
  //the Intensity Value and send it
  Light_Intensity=LightSensor.GetLightIntensity();
  delay(50);

  SensorValue=map(Light_Intensity,0,2000,255,0);
  SensorValue=constrain(SensorValue,255,0);
  digitalWrite(LedPin,SensorValue);
  // ready to another reading .
}

 


On the library attachment You can find LCD _BH1750 Code , connect a LCD1602 AND BH1750 Together  

code :

/*
  This is a simple code to test BH1750FVI Light senosr
  communicate using I2C Protocol
  this library enable 2 slave device address
  Main address  0x23
  secondary address 0x5C
  connect this sensor as following :
  VCC >>> 3.3V
  SDA >>> A4
  SCL >>> A5
  addr >> A3
  Gnd >>>Gnd

  Written By : Mohannad Rawashdeh
 
*/

// First define the library :
#include <BH1750FVI.h> // Sensor Library
#include <Wire.h> // I2C Library
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
uint16_t Light_Intensity=0;
// Call the function

BH1750FVI LightSensor;


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  lcd.begin(16, 2);

//  call begin Function so turn the sensor On .
  LightSensor.begin();
  LightSensor.SetAddress(Device_Address_H); //Address 0x5C
  LightSensor.SetMode(Continuous_H_resolution_Mode);
  lcd.setCursor(0, 0);
  lcd.print("BH1750 Sensor");
  lcd.setCursor(1, 1);
  lcd.print("Please wait...");
  delay(3000);
  lcd.clear();

}

void loop() {
  // put your main code here, to run repeatedly:
   lcd.clear();
   lcd.setCursor(0, 0);
   lcd.print(" Intensity = ");
   lcd.setCursor(5, 1);
   Light_Intensity = LightSensor.GetLightIntensity();
   lcd.print(Light_Intensity);
   lcd.print(" Lux");
   delay(2000);
  
}



This Video For it 

Step 6: BH1750FVI Library

Picture of BH1750FVI Library

the BH1750FVI Library is easy to use .

first , to include the library :

#include <BH1750FVI.h>

give a name for a library to call function through

BH1750FVI LightSensor ;

to begin the library , make sensor ready to use , call :

begin();

force sensor to power Down , call :

Sleep();


to wake up the sensor , call :

Reset();


toSet the address for this sensor ,you can use 2 different address , you must connect Addr pin to A3 .
Device_Address_H "0x5C"
Device_Address_L "0x23"

call :

SetAddress(Device_Address);


set the Working Mode for this sensor , call :

SetMode( Mode);


which mode would be :

    Continuous_H_resolution_Mode
    Continuous_H_resolution_Mode2
    Continuous_L_resolution_Mode
    OneTime_H_resolution_Mode
    OneTime_H_resolution_Mode2
    OneTime_L_resolution_Mode

and  finally to get Intensity value call function :


GetLightIntensity();


return value of intensity , 2 Byte .


 finally , you can use this sensor to build a simple solar Tracker system or light seeker robot "I will discuss about later "

hope give me a feedback for circuit and library , to make it better .

thank you

Comments

misaelrnguho (author)2017-08-05

How can I interface the BH1750 light sensor to arduino uno rev 3 and LED bulb to achieve automatic dimming LED bulb?

you need to measure the Max and min reading of the light sensor , and then map the reading to become from 0 - 255 , you can check ma function from here for more details
https://www.arduino.cc/en/Reference/Map

MartinF119 (author)2017-07-23

I constantly got 54612 lux on MEGA 2560. I fixed it by using 20 SDA and 21 SCL pin and mainly changing to Device_Address_L in the code since I did not connect ADDR pin to A3. In fact my sensor had no wire going from ADDR pin. Low state on ADDR corresponds to Device_Address_L.

BioMakerCR made it! (author)2017-07-11

Thank you for your knowledge! I constantly gives 54612 lux, but I solved it resoldering.

yveau (author)2017-03-29

Super clear tutorial, works like a charm !!! Many thanks

Mohannad Rawashdeh (author)yveau2017-04-21

My pleasure

ryanerossramos (author)2017-04-20

sir i have a project, lux meter using bh1750. why it is uncovered sensor?

and why the existing digital luxmeter made in taiwan have an cover please explain thank you.. need it so badly.

Honestly I don't know why !

RafaelG42 (author)2017-03-12

Excelent tutorial, work realy good

my pleasure

rameela20 (author)2016-07-16

Does BH1750 work with mega 2560 board also?It worked fine with uno.But although i tried i couldn't get it successfully connected with mega.It constatntly gives 54612 lux as the intensity.what should i do to make it work with mega?Please help me out here.I am trying to do a project with arduino to measure light intensity

TiếnB1 (author)rameela202017-02-15

Because the I2C pin of Mega 2560 is different from Uno.

To work with Mega 2560 Board, You must connect :

ADDR pin > pin 17 (Mega RX2 pin)

SDA pin > pin 20 (Mega SDA pin)

SCL pin > pin 21 (Mega SCL pin)

Or you can change the pin on the library.

TiếnB1 (author)TiếnB12017-02-21

Just ADDR Pin

that's totally right

it must works as well with mega since it use i2c protocol
could you please add image for the connection and the results you have

diy_bloke (author)rameela202016-09-04

are you using the proper SDA and SCL pins?

AlanGP (author)2017-02-11

Hi Mohannad,

Many thanks for this. A very useful tutorial.

Alan

my pleasure :)

camilo ortega (author)2016-09-10

hey i was trying to use the sensosr, but doesn't matter how i set it up, it always gives me 54612 lx. why does it happens? someone can help me? thanks

TiếnB1 (author)camilo ortega2017-02-15

Because the I2C pin of Mega 2560 is different from Uno.

To work with Mega 2560 Board, You must connect :

ADDR pin > pin 17 (Mega RX2 pin)

SDA pin > pin 20 (Mega SDA pin)

SCL pin > pin 21 (Mega SCL pin)

Or you can change the pin on the library.

miarella (author)2016-10-26

overall, how long does this entire process take? (for a beginner)

denielle deloso (author)2016-09-28

good day sir. is this module be programmed by "if ,then , else condition" ? that if it detects <100 lux on a certain bulb, the GSM will be triggered to send a msg to notify that the bulb is not on its standard lux amunt/ or should we say "in fault".. Is this possible ? Please advice sir.Thank you :)

may also find this interesting

https://www.instructables.com/id/Send-SMS-with-arduino-no-shield-/

es sir I mean by using arduino :) Sir do you have any idea about it ? that if it detects <100 lux on a certain bulb, the GSM will be triggered to send a short msg to notify that the bulb is not on its standard lux amount/ or should we say "in fault".?? Pls advice sir :) Thanks :)

yes that is possible. The GSM shield can send text messages, and you yourself can decide what the trigger is for that.
I think I sent you a link in facebook about a way to do it without a gsm shield that I think connected with an old GSM through bluetooth.

As it is possible to program some gsm's to take an action when you close a contact in the earphone jack, it may be possible to program an old gsm such that it sends a standard SMS and have the arduino trigger a relay.

You also could connect your Arduino to internet and attach to an sms service, or instead of an sms get a tweet from twitter.

or... you could forget about the arduino and get a cheap ESP8266 board (say for 2.30 euro/150 php) and connect to internet with that.. should you decide to go via internet

denielle, the BH1750 is just a sensor and cannot be programmed itself (but apologies if i misunderstood yr question), but ofcourse the arduino or other microprocessor can do that. There are ofcourse various ways of doing that, either with a gsm shield, or a messenger service or could consider sending a tweet instead of a message

TâmH5 (author)2015-11-18

I have a project about Solar panel, that I have use 2 Bh1750 to collect the information and compare to each other, depend on that, I can control the step-motor, make sure the Solar panel receive most light and spread on over the panel. And I dont know how to get the address of the second Bh1750. Can any body help me? Thank u!

diy_bloke (author)TâmH52016-09-04

the addresses are 0x5C and 0x23, depending on wether ADDR is HIGH or LOW

artmez (author)2016-05-18

Not bad, but in need of some polish for itsrough "edges".

The comments/questions about setting and using I2C slave address are newbie question. I think the confusion stems from the article saying that the sensor's
ADDR pin line MUST be tied to the Arduino's A3 pin. While that may be OK for testing (to verify the code), there is no reason to design a real embedded system with dynamic I2C slave addressing as all the sensors will be hard-wired. A major benefit of I2C is that it allows using common data and clock lines to communicate with potentially a LOT of peripherals. It's the slave address that is issued over the I2C bus that determines which sensor SHOULD respond. Manufacturers that are licensed and registered to use I2C have address(es) assigned that have little chance of being the same as some other peripheral's address(es). If you are doing an AD HOC design of a slave I2C peripheral, then you may get into trouble, but only if you want your peripheral to be used anywhere.

The same issues apply to USB's VID/PID (vendor and product IDs). It those aren't coordinated, then everyone loses through the confusion. But it doesn't explain why there isn't a "pool" of open USB addresses for debug and testing or why it's a license violation to "share" one that is "owned". Most, if not all, of the first USB devices on PCs used the default ones in Microsoft's DDK sample code and library and still do!

BTW, there are lots other light sensors out there, both simple and complex. Some applications may not need the sophistication (or added expense) of this sensor. A simple CdS sensor or Silicon photo transistor may be suitable with the right adaptation.

diy_bloke (author)artmez2016-09-03

thanks. I was already wondering what the use was of connecting to A3

krunalsoni made it! (author)2016-07-25

This sketch requires BH1750.h library.

You can download the library here

https://docs.google.com/file/d/0B4qM0hq-OmC1RHhEcXRNSmZ1YW8/

I made it from http://sunrobotics.co.in/index.php?main_page=product_info&cPath=22&products_id=415

tipusultan (author)2016-04-04

sir, can this digital light sensor module be interfaced to fpga to sense the indoor i'light intensity and adjust the LED brightness???

AnkanP (author)2016-03-11

Hello, I wanted to know how to connect more than one BH1750 sensors to a
single arduino so that the addresses do not conflict. The output from each
sensor should be used to do a specific task, like turning on specific
LEDs corresponding to respective sensor. Can anybody give the connection
details and the sketch to be uploaded to the arduino. Thanks in
advance.

AnkanP (author)2016-03-11

Hello, I wanted to know how to connect more than one BH1750 sensors to a
single arduino so that the addresses do not conflict. The output from each
sensor should be used to do a specific task, like turning on respective
LEDs corresponding to respective sensors. Can anybody give the connection
details and the sketch to be uploaded to the arduino? Thanks in
advance.

AaromaleP (author)2015-09-28

i want to interface this sensor with lpc1768 .please give me sample code for this...

ravirajD (author)2015-06-29

I am working on a similar project and got stuck on a proint, and I hope somebody will guide me..the requirement is " I have a hardware devcie which has different color LED's (Green,red and Yellow color) and I have to calculate how many times each color LED glows for each mode of operation,

So what kind of light sensor I have to use with Arduino UNO to achieve this

jm-l (author)ravirajD2015-09-11

easiest way would be to actually take an electric reading at the LED pin (i.e. connect the cathode to a pin for example) and measure what's going on there... 0 probably your LED is off and above a threshold (say a few V) LED is on...

if you don't have access to the internals of your device, then just stick a photoXXX (XXX= resistor/diode/transistor depending on your needs) in front of each LED (use "patafix" to hold the photoXXX just in front of the diode) and measure what your photoXXX sees.

flopp999 (author)2015-06-12

I have my BH1750 outdoor to test and I get 54612, if I move it to the shadow it drops, so the sensor is working.

My question is how to change the sensor-range? Or is the sensor getting a maximum input from the sun. Weather now is zero-clouds.

saeedjy (author)2015-02-13

I tried to use our library and get my BH1750fvi sensor to work. However it did not. It gave me a constant output of 54612 :(

Could you help? I tried on arduino mega

MalW1 (author)saeedjy2015-04-08

On a mega Rev 3 I got it to work by using pins 20 and 21, new dedicated sda and scl pins

jwtrexler (author)2015-02-24

(1) Could someone please explain why the CD4050 works? It is my understanding the 4050 is a mono-directional logic buffer, and

(2) Can the BH1750 be modified to eliminate its internal pull down resistors so I can include it with multiple other I2C sensors?

FrankH3 (author)2015-01-26

test:23: error: 'BH1750FVI' does not name a type
test.ino: In function 'void setup()':
test:28: error: 'LightSensor' was not declared in this scope
test:36: error: 'Device_Address_H' was not declared in this scope
test:53: error: 'Continuous_H_resolution_Mode' was not declared in this scope
test.ino: In function 'void loop()':
test:61: error: 'LightSensor' was not declared in this scope

calimerau57 (author)2015-01-16

Hello, I have exactly the same problem as him but on the Arduino Yun! Could you help me?

wozuiren. (author)2015-01-06

In Step 3 on your diagram with the IC CD4050, the wiring seems to be incorrect. According to the CD4050 pin-out, pin 13 is not used. Please check.

wozuiren. (author)2015-01-06

In Step 3 on your diagram with the IC CD4050, the wiring seems to be incorrect. According to the CD4050 pin-out, pin 13 is not used. Please check.

wozuiren. (author)2015-01-06

In Step 3 on your diagram with the IC CD4050, the wiring seems to be incorrect. According to the CD4050 pin-out, pin 13 is not used. Please check.

wozuiren. (author)2015-01-06

In Step 3 on your diagram with the IC CD4050, the wiring seems to be incorrect. According to the CD4050 pin-out, pin 13 is not used. Please check.

henrikekblad (author)2014-09-25

If you'd like to make the light sensor wireless (send the lux value over-the-air somewhere), have a look at the MySensors project. You'll find an light sensor example here:
http://www.mysensors.org/build/light

suvinks (author)2014-05-27

I tried to use our library and get my BH1750fvi sensor to work. However it did not. It gave me a constant output of 54612 :(

Could you help? I tried on both arduino mega and duemilinove

vishnuprakash90 (author)suvinks2014-07-17

I too got the same output!..Did u debug it?

About This Instructable

190,355views

222favorites

License:

Bio: Maker, PCB designer , electronics instructor from Jordan just one word ! I Adore electronics follow me on FB https://www.facebook.com/Mohannad-Rawashdeh-Raw-774983565988641/
More by Mohannad Rawashdeh:Convert Your Pringles Cans to RTTTL Audio PlayerTTP224 Digital Touch Sensor Applications Using ArduinoRF 315MHz/433MHz Wireless and Arduino...again!
Add instructable to: