Preview build — page text is a draft awaiting human review. Code badges come from real compiles. The flasher is real but not yet hardware-tested; the Playground is still a preview.

BH1750 light sensor with Arduino Uno — real lux readings over I2C

Wire a GY-302 BH1750 to an Arduino Uno R3 over I2C, set its address with ADDR, and read calibrated light levels in lux from a dark room to direct sun.

Arduino C++Verified — core avr 1.8.8, BH1750 1.3.0, 3 Nov 2026Compile-only

Community draft — report a mistake

The BH1750 measures light in lux, the same unit a professional light meter uses. That makes it better than an LDR for automatic lighting, plant-growth logging or checking whether a study table is bright enough. The GY-302 board costs about ₹120.

On the Uno it connects to 5V, GND and SDA/SCL (the same signals as A4/A5). Tie ADDR to GND for address 0x23, the library’s default. The board has its own regulator, so 5 V is fine.

The sketch reads in high-resolution mode (1 lx steps) once a second and adds a plain-English description, from dark to direct sun.

Wiring

Arduino Uno R3Only the pins used are shown · 5 V logicBH1750 lux sensor (GY-302)5VGNDSDA · 18SCL · 19VCCGNDSCLSDAADDR
Every connection
Arduino Uno R3BH1750 lux sensor (GY-302)WireNotes
5VVCCredThe GY-302 has a 3.3 V regulator, so 5 V in is fine.
GNDGNDblack
SCLSCLyellowSame signal as A5
SDASDAblueSame signal as A4
GNDADDRblackAddress 0x23. ADDR to 3.3 V or 5 V = 0x5C (for a second sensor).

3–5 V (on-board regulator) part, 5 V board. The GY-302 has a 3.3 V regulator and accepts 3–5 V on VCC; its pull-ups suit both 3.3 V and 5 V boards.

Board quirks

  • Unlike an LDR, the BH1750 gives calibrated lux, so readings mean the same on every board: about 300–500 lx at a study desk, 10 000+ lx outdoors in shade, up to about 100 000 lx in Indian midday sun.
  • It tops out at 65 535 lx in the default mode. In direct summer sun it saturates; put a piece of white paper over it, or use a lower-sensitivity setting.
  • The sensor faces up from the side with the small black chip. Behind glass or plastic it reads lower — compare once without the cover and scale.
  • Like every I2C part on the Uno it uses SDA/SCL (A4/A5), and it shares the bus happily with an LCD or OLED.

Code

bh1750-uno.inoArduino C++Open in PlaygroundOpen in PlaygroundFlash
// BH1750 (GY-302) light sensor on an Arduino Uno R3, I2C.
// VCC → 5V, GND → GND, SCL → SCL (A5), SDA → SDA (A4), ADDR → GND (address 0x23).
#include <Wire.h>
#include <BH1750.h>

BH1750 lightMeter(0x23);

void setup() {
  Serial.begin(9600);
  Wire.begin();
  if (!lightMeter.begin(BH1750::CONTINUOUS_HIGH_RES_MODE)) {
    Serial.println(F("BH1750 not found at 0x23 - check wiring and ADDR"));
    for (;;) {}
  }
  Serial.println(F("BH1750 ready (1 lx resolution, new value every ~120 ms)"));
}

void loop() {
  float lux = lightMeter.readLightLevel();
  Serial.print(F("Light "));
  Serial.print(lux, 0);
  Serial.print(F(" lx  "));
  if (lux < 10) Serial.println(F("dark"));
  else if (lux < 200) Serial.println(F("dim room"));
  else if (lux < 1000) Serial.println(F("bright room"));
  else if (lux < 20000) Serial.println(F("daylight / shade"));
  else Serial.println(F("direct sun"));
  delay(1000);
}

Library: BH1750 (Christopher Laws) — compiled with BH1750 1.3.0.

Expected serial output

Serial Monitor · 9600Output
BH1750 ready (1 lx resolution, new value every ~120 ms)
Light 412 lx  bright room
Light 3 lx  dark
Light 18650 lx  daylight / shade

Common errors

“BH1750 not found at 0x23”

ADDR is floating or HIGH (then it answers at 0x5C), or SDA/SCL are swapped. Run the I2C scanner.

Reads 54612 or −2 at random

An I2C read failed, often on long wires. Keep wires under 50 cm and solder the header pins.

Value lower than a phone light meter app

Phone apps are rough guesses. Check the sensor isn’t tilted or shaded by its own wires.

↑↓ to move · Enter to open