The BH1750 ambient light sensor LED brightness combination is one of the most practical and energy-efficient automation setups you can build with an Arduino. Whether you want to create smart room lighting that dims automatically when it’s sunny outside or build an outdoor sign that brightens at night, the BH1750 gives you precise lux measurements to drive intelligent LED control. In this tutorial, we cover everything from hardware wiring and I2C communication to writing clean Arduino code that adjusts LED intensity in real time.
What Is the BH1750 Ambient Light Sensor?
The BH1750 is a 16-bit digital ambient light sensor manufactured by ROHM Semiconductor. It communicates over the I2C bus and delivers calibrated lux values directly — no analog-to-digital conversion math required on your microcontroller. The sensor measures illuminance from 1 lux up to 65,535 lux, covering everything from a dim bedroom to direct tropical sunlight.
Key specifications of the BH1750:
- Supply voltage: 2.4 V to 3.6 V (5 V tolerant on most breakout boards)
- Interface: I2C (address 0x23 or 0x5C, selectable via ADDR pin)
- Resolution modes: 1 lux, 0.5 lux, or 4 lux depending on measurement time
- Measurement range: 1 – 65,535 lux
- Spectral response: close to human eye sensitivity (peak ~560 nm)
The GY-302 breakout module is the most common form factor, featuring a 3.3 V regulator and level shifters so you can connect directly to a 5 V Arduino without damaging the sensor.
Why Use BH1750 for LED Brightness Control?
Traditional light-dependent resistors (LDRs) give a vague analog voltage that varies with temperature and age. The BH1750, in contrast, outputs a calibrated lux value that correlates directly to what the human eye perceives. This makes your LED dimming curve predictable and consistent across different environments and microcontroller boards.
Advantages over LDR-based solutions:
- No ADC noise or calibration drift over time
- Two sensors on the same I2C bus using different addresses
- Built-in 50/60 Hz light noise rejection
- Consistent readings from batch to batch (±20% accuracy)
For a classroom, office, or greenhouse application where repeatable behavior matters, the BH1750 is the clear winner.
Components Needed
To build the automatic LED brightness controller you will need:
- Arduino Uno or Nano (or any I2C-capable board)
- BH1750 GY-302 breakout module
- High-brightness LED (or LED strip with MOSFET driver)
- IRLZ44N logic-level MOSFET (for PWM LED dimming)
- 10 kΩ resistor (gate pull-down)
- 100 Ω resistor (gate resistor)
- Breadboard, jumper wires
- 12 V power supply (for LED strip) or USB power for single LEDs
If you already have a DHT11 or DS18B20 temperature sensor on your project, you can share the same power rails since the BH1750 draws only 190 µA during measurement.
DHT11 Digital Relative Humidity and Temperature Sensor Module
Add temperature and humidity sensing alongside your BH1750 light measurements to build a comprehensive environmental monitoring node.
Circuit Wiring and I2C Setup
Wiring the BH1750 to an Arduino Uno is straightforward:
| BH1750 Pin | Arduino Uno Pin |
|---|---|
| VCC | 5V (via onboard regulator) |
| GND | GND |
| SCL | A5 |
| SDA | A4 |
| ADDR | GND (address 0x23) or 3.3V (0x5C) |
For the MOSFET LED driver, connect the gate to Arduino PWM pin D9 through a 100 Ω resistor. Put the 10 kΩ pull-down between the gate and GND. The drain goes to the negative terminal of your LED strip; the source goes to GND. The positive terminal of the LED strip connects to your 12 V supply.
Arduino Code for Automatic LED Dimming
Install the BH1750 library by Christopher Laws via the Arduino Library Manager before uploading the sketch.
#include <Wire.h>
#include <BH1750.h>
BH1750 lightMeter;
const int ledPin = 9; // PWM pin
// Lux thresholds
const float MAX_LUX = 1000.0; // bright daylight
const float MIN_LUX = 10.0; // very dark room
void setup() {
Wire.begin();
lightMeter.begin(BH1750::CONTINUOUS_HIGH_RES_MODE);
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
}
void loop() {
float lux = lightMeter.readLightLevel();
Serial.print("Lux: "); Serial.println(lux);
// Invert: more ambient light = dimmer LED
float ratio = 1.0 - constrain((lux - MIN_LUX) / (MAX_LUX - MIN_LUX), 0.0, 1.0);
int pwmValue = (int)(ratio * 255);
analogWrite(ledPin, pwmValue);
delay(500);
}
The constrain() function clamps the ratio between 0 and 1 so the LED never receives an out-of-range PWM value. You can adjust MAX_LUX and MIN_LUX to match your specific environment — a greenhouse needs different thresholds than a kitchen counter.
Calibration and Lux Thresholds
To calibrate your setup, open the Serial Monitor and note the lux reading under different real-world conditions:
- Overcast outdoor day: 1,000 – 10,000 lux
- Well-lit office: 300 – 500 lux
- Living room with ceiling light: 50 – 150 lux
- Candlelit room: 10 – 30 lux
- Moonlit night: 0.1 – 1 lux
Set your MAX_LUX to the value where you want the LED fully off, and MIN_LUX to where you want it fully bright. A hysteresis band of ±5 lux prevents the LED from flickering when ambient light is at the threshold level. You can implement hysteresis by maintaining a previous PWM state and only updating when lux changes by more than 5.
BMP280 Barometric Pressure and Altitude Sensor I2C/SPI Module
Share the I2C bus with your BH1750 and log barometric pressure alongside ambient light data for complete weather station builds.
Advanced Upgrades: Multiple Zones and Data Logging
Once your basic dimming loop works, consider these upgrades:
1. Two-Sensor Zone Control
Use two BH1750 sensors on the same I2C bus — set one ADDR pin to GND (0x23) and the other to 3.3V (0x5C). This lets you control two LED zones independently based on local ambient light, ideal for a room with a window on one side only.
2. Sunrise / Sunset Simulation
Combine the BH1750 reading with a DS3231 real-time clock. During morning hours, ramp LED brightness from 0 to full over 30 minutes even if the lux sensor reports darkness (cloudy day). This mimics natural light cycles for plant growth or human circadian rhythm support.
3. MQTT Data Logging with ESP32
Replace the Arduino with an ESP32 and publish lux values to an MQTT broker every 10 seconds. Use Node-RED or Grafana to plot light levels over time and correlate with energy usage from your smart plug.
4. Adaptive Display Backlight
Hook the BH1750 to the I2C bus alongside an OLED display. Automatically dim the display backlight in dark rooms to reduce eye strain — a very practical feature for bench instruments and weather stations.
LM35 Temperature Sensors
Pair with your BH1750 project to also monitor LED driver temperature, triggering a shutdown if the MOSFET gets too hot.
GY-BME280-3.3 Precision Altimeter Atmospheric Pressure Sensor Module
Upgrade your environmental node with the BME280 for temperature, humidity, and pressure alongside BH1750 light data — all on one I2C bus.
Frequently Asked Questions
Q: Can I use the BH1750 outdoors?
Yes, but protect it from direct rain. House it in a white weatherproof enclosure or a radiation shield so sunlight can reach the sensor window without water ingress. The sensor itself handles up to 65,535 lux, which covers full tropical sunlight.
Q: My BH1750 always reads 0 lux. What is wrong?
Check your I2C address — make sure the ADDR pin matches the address you pass to lightMeter.begin(). Also verify SDA/SCL connections and run the I2C scanner sketch to confirm the sensor appears on the bus.
Q: Is PWM dimming safe for all LEDs?
High-frequency PWM (above 1 kHz) is imperceptible to the human eye and safe for most LEDs. The Arduino default PWM is ~490 Hz for most pins and ~980 Hz for pins 5 and 6. Using an IRLZ44N MOSFET rated for logic-level gate drive at 5 V ensures full saturation and minimal heating.
Q: Can I use the BH1750 with a Raspberry Pi?
Yes. Enable the I2C interface in raspi-config and use the Python smbus2 library. Several pre-built Python wrappers exist on PyPI that mirror the Arduino library API.
Q: What is the difference between BH1750 and TSL2561?
Both are I2C lux sensors. The TSL2561 has two photodiodes (visible + IR) allowing better correction for non-daylight light sources. The BH1750 is simpler, cheaper, and good enough for most general-purpose ambient light applications where extreme infrared correction is not needed.
Ready to Build Your Light-Sensing Project?
Browse our full range of environmental sensors and microcontroller accessories at Zbotic.in. We carry DHT sensors, BMP280, BME280, DS18B20, and much more — all with fast shipping across India.
Add comment