Source: https://mokxi.com/learn/arduino-bh1750
Updated: 2026-11-02

Learn

# Measure light in lux with a BH1750 on an Arduino

Beginner

Written by the Mokxi team, updated November 2, 2026

Start building free Open the editor

Or see every lesson.

- 465 parts on the bench
- 43 boards running now
- 1.00x real time, on every board

Click to open it in the editor

A BH1750 on I2C and an LED on pin 9, on a simulated ATmega328P. Drag the slider over the sensor.

The BH1750 is a light sensor that gives you a real number: lux, the unit a light meter uses. A light-dependent resistor gives a reading that depends on the resistor beside it and the batch it came from. The BH1750 is filtered to match the human eye and reports lux over I2C, with nothing for you to calibrate. The common module is the GY-302.

The circuit above is an Uno with a BH1750 on its I2C pins and an LED on pin 9 that gets brighter as the room gets darker. Drag the slider over the sensor to change the light, and the serial monitor prints the lux and the lamp’s brightness five times a second. It runs in your browser on the sketch below.

## What you need

- An Arduino Uno
- A BH1750 module (GY-302)
- An LED and a 220 ohm resistor
- A breadboard and jumper wires

## Wiring

Part and pin | Goes to | Note

BH1750 VCC | 5 V | The module has its own 3.3 V regulator

BH1750 GND | GND |

BH1750 SDA | SDA (A4) | The module carries the pull-ups

BH1750 SCL | SCL (A5) |

BH1750 ADDR | Not connected | Address 0x23; high makes it 0x5C

LED anode, through 220 ohm | Pin 9 | A PWM pin, so it can fade

## What a lux reading means

A dark room is a few lux. A classroom is a few hundred, an overcast day outdoors a few thousand, and direct sun around a hundred thousand. The slider over the sensor is logarithmic for that reason: the middle is a classroom and the right end is the sun.

The chip counts light at 1.2 counts per lux and stops at 65535 counts. Divide and that is 54612 lux, the most it can report. Drag the slider to the far right and the reading sits at "light 54612 lx", as a real one does in full sun.

## The sketch, step by step

BH1750 lightMeter makes the sensor object, and lightMeter.begin() starts it in its default mode: a new reading every 120 milliseconds at 1 lux resolution. begin() returns false if the sensor does not answer, and the sketch says so.

In loop(), measurementReady() says whether a new reading is in. readLightLevel() gives the lux as a float, which is what most tutorials print. This sketch does sums with the reading, and the Uno has no floating-point hardware, so it uses readLightLevelCentis() instead: the same reading in hundredths of a lux, as a whole number, divided by 100.

Then the lamp. Under 20 lux it is full on, 255. Over 500 it is off. In between it fades: brightness = 255 x (500 - lux) / 480. At the start the light is 300 lux and the line reads "light 300 lx lamp 106". At 100 lux it is 212, and at 20 lux it is 255.

The lux night lamp sketch, trimmed

## Modes and two sensors on one bus

begin() takes a mode. CONTINUOUS_HIGH_RES_MODE, the default, measures over and over at 1 lux. CONTINUOUS_LOW_RES_MODE measures in 16 ms at 4 lux steps. The ONE_TIME modes take a single reading and power the chip down, which saves battery in a logger that wakes once a minute.

The ADDR pin picks the address: 0x23 when it is low or open, 0x5C when it is high. Tie one sensor’s ADDR to 3.3 V and you can read two on the same two wires, one pointed at the sky and one at the room.

## Common mistakes

Not checking the reading. With SDA disconnected this sketch prints "no BH1750: check SDA, SCL and power" and then "light -1 lx", because the library’s readings go negative when the sensor does not answer, and the lamp goes full on. Treat a negative reading as an error, not as darkness.

Reading before the first measurement is done. Until the first 120 ms have passed the reading is 0.

Two sensors with ADDR the same. They both answer at 0x23. Tie one high.

Expecting it to see sunlight through a window at full scale. It stops at 54612 lux, and direct sun is more than that.

The wrong pins for I2C. On an Uno SDA is A4 and SCL is A5; the SDA and SCL pins by the USB socket are the same two lines.

## Questions

How do I connect a BH1750 to an Arduino Uno?

VCC to 5 V, GND to GND, SDA to A4 and SCL to A5. Leave ADDR open for address 0x23. The GY-302 module has a regulator and pull-ups, so nothing else is needed.

BH1750 or LDR: which should I use?

An LDR is cheaper and fine for "is it dark". The BH1750 gives lux you can compare with a light meter or a datasheet, with no calibration, so use it when the number matters.

Which BH1750 library does this use?

BH1750 by Christopher Laws, the one the Library Manager finds first. Mokxi includes it, so #include <BH1750.h> works without installing anything.

What is the maximum lux a BH1750 can read?

In its default mode, 54612 lux: 65535 counts divided by 1.2. Raising the measurement time with setMTreg() reaches further into the dark and saturates sooner.

Related

## Keep going

Arduino LDR Night Light (Photoresistor) I2C Explained: Addresses, Acknowledges and Pull-Ups Arduino PWM Fade: analogWrite, Pins and the Curve PWM: Faking an Analog Voltage on a Digital Pin How the BH1750 is modeled The LDR, for comparison The Arduino Uno simulator The project page, with the full sketch Beginner

## Build this for real

Open the editor, change a value and watch the number move with it. Nothing to install, and no account needed.

Start building free Open the editor
