Documentation

BH1750 Pre-Soldered Light Intensity Module
Documentation / BH1750 Pre-Soldered Light Intensity Module

BH1750 Pre-Soldered Light Intensity Module

Overview

The BH1750 is a digital ambient-light sensor from ROHM that outputs lux values directly over I2C — no math, no voltage-to-lux conversions, no photoresistor guesswork. It's a 16-bit measurement in a tiny SMD package, with a range of ~1 to 65,535 lux and excellent spectral response to human-visible light. That makes it a go-to choice for auto-brightness displays, sun trackers, greenhouse controllers, smart-home lighting, and anywhere you need real photometric readings.

ShillehTek's pre-soldered BH1750 module includes an onboard regulator and I2C pull-ups, so it runs reliably on both 3.3V and 5V systems. The ADDR pin selects the I2C address: float or tied LOW gives 0x23, and tied HIGH gives 0x5C — so you can run two BH1750s on the same bus.

This manual covers specifications, the pinout, wiring for Arduino, ESP32, Raspberry Pi, and the Pico, a working "hello world" code example for each platform, and FAQs about measurement modes, saturation, and calibration.

At a Glance

Voltage
2.4V - 3.6V (5V tolerant)
Interface
I2C
I2C Address
0x23 / 0x5C
Range
1 - 65,535 lux
Resolution
1 lux (default)
Pins
5 (Pre-Soldered)

Specifications

Parameter Value
Sensor IC ROHM BH1750FVI
Operating Voltage (module) 3.3V - 5V (onboard regulator)
Chip Voltage 2.4V - 3.6V (regulated internally)
Communication I2C
I2C Addresses 0x23 (ADDR = LOW) / 0x5C (ADDR = HIGH)
Measurement Range 1 - 65,535 lux
Resolution 1 lux (H-res) / 0.5 lux (H-res2) / 4 lux (L-res)
Conversion Time ~120 ms (H-res) / ~16 ms (L-res)
Spectral Response Similar to human eye
Current Draw ~120 μA (active)
Pin Count 5 (VCC, GND, SCL, SDA, ADDR)

Pinout Diagram

BH1750 Pinout Diagram

Wiring Guide

Arduino Wiring

Connect to the Arduino's hardware I2C pins. Leave ADDR unconnected or tied to GND for the default 0x23 address.

Module Pin Arduino Pin
VCC 5V
GND GND
SCL A5 (SCL)
SDA A4 (SDA)
ADDR Not connected (address 0x23)
Tip: Tie ADDR to VCC to switch to 0x5C — useful when you already have a 0x23 device on the bus.

ESP32 Wiring

The ESP32's 3.3V rail is perfect for the BH1750 module. Use the default I2C pins.

Module Pin ESP32 Pin
VCC 3.3V
GND GND
SCL GPIO 22
SDA GPIO 21
ADDR Not connected

Raspberry Pi Wiring

Use hardware I2C. Enable I2C via sudo raspi-config before running your code.

Module Pin Raspberry Pi Pin
VCC 3.3V (Pin 1)
GND GND (Pin 6)
SCL GPIO 3 (Pin 5, SCL)
SDA GPIO 2 (Pin 3, SDA)
ADDR Not connected
Tip: Verify detection with i2cdetect -y 1. The default address is 0x23.

Raspberry Pi Pico Wiring

Connect to I2C0 on GP0/GP1. Works in both MicroPython and C SDK.

Module Pin Pico Pin
VCC 3.3V (Pin 36)
GND GND (Pin 38)
SCL GP1 (Pin 2, I2C0 SCL)
SDA GP0 (Pin 1, I2C0 SDA)
ADDR Not connected

Code Examples

Arduino

bh1750_read.ino
// BH1750 - Read ambient light in lux
// Requires: BH1750 library by Christopher Laws

#include <Wire.h>
#include <BH1750.h>

BH1750 lightMeter;

void setup() {
  Serial.begin(9600);
  Wire.begin();
  if (!lightMeter.begin()) {
    Serial.println("BH1750 not found. Check wiring.");
    while (1);
  }
  Serial.println("BH1750 ready.");
}

void loop() {
  float lux = lightMeter.readLightLevel();
  Serial.print("Light: ");
  Serial.print(lux);
  Serial.println(" lx");
  delay(500);
}

ESP32

bh1750_esp32.ino
// BH1750 on ESP32 via I2C (GPIO21 SDA, GPIO22 SCL)
// Requires: BH1750 library

#include <Wire.h>
#include <BH1750.h>

BH1750 lightMeter;

void setup() {
  Serial.begin(115200);
  Wire.begin(21, 22);
  if (!lightMeter.begin()) {
    Serial.println("BH1750 not found.");
    while (1);
  }
}

void loop() {
  float lux = lightMeter.readLightLevel();
  Serial.printf("Light: %.1f lx\n", lux);
  delay(500);
}

Raspberry Pi

bh1750_read.py
# BH1750 on Raspberry Pi via I2C
# Install: pip install smbus2
# Enable I2C: sudo raspi-config -> Interface Options -> I2C

import smbus2
import time

BH1750_ADDR = 0x23
CONT_H_RES  = 0x10   # continuous 1-lux resolution

bus = smbus2.SMBus(1)
bus.write_byte(BH1750_ADDR, CONT_H_RES)
time.sleep(0.2)  # first conversion

while True:
    data = bus.read_i2c_block_data(BH1750_ADDR, 0x00, 2)
    raw  = (data[0] << 8) | data[1]
    lux  = raw / 1.2
    print(f"Light: {lux:.1f} lx")
    time.sleep(1)

Raspberry Pi Pico (MicroPython)

bh1750_pico.py
# BH1750 on Pico via I2C0 (GP0 SDA, GP1 SCL)

from machine import I2C, Pin
import time

BH1750_ADDR = 0x23
CONT_H_RES  = 0x10

i2c = I2C(0, sda=Pin(0), scl=Pin(1), freq=100000)
print("I2C scan:", [hex(d) for d in i2c.scan()])

i2c.writeto(BH1750_ADDR, bytes([CONT_H_RES]))
time.sleep_ms(200)

while True:
    data = i2c.readfrom(BH1750_ADDR, 2)
    raw  = (data[0] << 8) | data[1]
    lux  = raw / 1.2
    print("Light: {:.1f} lx".format(lux))
    time.sleep(1)

Frequently Asked Questions

What is the default I2C address of the BH1750?
With ADDR left floating or tied to GND, the address is 0x23. Tie ADDR to VCC to switch to 0x5C — letting you run two BH1750s on the same I2C bus.
What's the difference between the measurement modes?
H-res (default) gives 1 lux resolution every 120 ms. H-res2 is 0.5 lux at the same rate. L-res gives 4 lux but updates every 16 ms — useful for fast-changing light. There are also one-shot versions of each that power down between reads for low-power designs.
Why does the sensor max out at 65,535 lux?
The BH1750 uses a 16-bit register for the raw value, so the practical ceiling is ~65,535 lux. Direct sunlight can reach ~100,000 lux, which will saturate the sensor. Shield it with a neutral density filter or mount it in indirect light for outdoor use.
Is 1 lux actually accurate?
The BH1750's linearity is ~±20% across its range. It's excellent for "is the room bright or dim?" decisions and auto-backlight dimming, but it's not a calibrated lux meter — for precision photometry, use a calibrated instrument.
Can I use it to detect flames or lasers?
It only responds to visible light, so it's fine for bright flames or lasers in the visible band. For IR lasers or flame front detection, use a dedicated IR photodiode or flame sensor.
Do I need external pull-ups on SDA/SCL?
No. The ShillehTek BH1750 module has onboard pull-ups, so external resistors aren't required for most setups.

Related Tutorials