Skip to content
SensorsLight

TSL2561 Luminosity Sensor

Dual-photodiode lux sensor with good accuracy across mixed lighting conditions.

Wiring & code for

TSL2561 practical reference

A precision light sensor using two photodiodes to separate infrared from visible light, giving more accurate lux readings than a single-diode LDR.

Key specifications

  • Sensor design: Two photodiodes — one sensitive to visible+infrared light, one to infrared only — allowing visible-light-only lux to be computed
  • Interface: I2C, up to 400kHz Fast mode
  • I2C address: 0x39 default; 0x29 or 0x49 selectable via the ADDR pin
  • Supply voltage: 2.7V–3.6V (breakout boards commonly accept 3.3-5V via onboard regulation)
  • Dynamic range: ~0.1 to 40,000+ lux
  • Resolution: 16-bit ADC per photodiode channel
  • Integration time: Selectable 13.7ms / 101ms / 402ms — trade-off between read speed and precision/max range
  • Interrupt: Programmable threshold interrupt available on the INT pin (open-drain, needs a pull-up)

Pinout and connection notes

ADDR pin behavior varies by breakout — check your specific board's silkscreen/datasheet: on most, floating gives 0x39, grounding gives 0x29, and tying to VCC gives 0x49. This lets you run up to three TSL2561s on one I2C bus without a multiplexer.

Integration time is a speed/precision trade-off — the default library setting is usually a reasonable middle ground (101ms), but low-light scenes benefit from the longer 402ms integration time for better resolution, while fast-changing light logging benefits from the shorter 13.7ms setting at the cost of some precision.

INT is open-drain — it needs an external pull-up resistor (or the microcontroller's internal pull-up) if you plan to use the interrupt-on-threshold feature; leaving it unconnected is fine if you're just polling lux values in code.

Lux isn't a single raw register read — computing an actual lux value requires combining both photodiode channels through the datasheet's piecewise formula (or CMOS/T-package-specific lookup table); this is handled automatically by libraries like Adafruit_TSL2561, but matters if you're reading registers manually.

  • VCC: Power, 3.3–5V DC depending on breakout
  • GND: Ground
  • SDA: I2C data line
  • SCL: I2C clock line
  • ADDR: I2C address select — float/GND-tie for 0x29, leave as-is for default 0x39, tie to VCC for 0x49 (varies slightly by breakout, check silkscreen)
  • INT: Programmable threshold interrupt output, open-drain — needs an external pull-up if used

Integration checklist

  1. Confirm the exact part number and breakout-board revision.
  2. Verify supply voltage, current demand, logic levels, and signal direction against the datasheet.
  3. Check controller pin assignments and bus address or interface mode against the example code.
  4. Power up with external loads disconnected, then test signals before full integration.
  5. If readings or communication fail, check power and ground first, then pin mapping, interface settings, and library initialization.

Troubleshooting and reproducibility

Record the board used, wiring, library/version, supply arrangement, and measured behavior. Use the selected board-specific wiring example as the source of truth. Never assume visually similar modules share identical voltage tolerance or pin order.

Board Integration

Library

Adafruit TSL2561 by Adafruit

Arduino IDE → Tools → Manage Libraries → search "Adafruit TSL2561" → Install (also installs the Adafruit Unified Sensor dependency)

Wiring

Component pinArduino Uno pinNote
VIN5V
GNDGND
SDAA4I2C data.
SCLA5I2C clock.

Swipe sideways to see every column →

C++
  • Unlike an LDR, this returns calibrated lux values by combining readings from its two photodiodes (visible+IR and IR-only) — that is what makes it far more consistent under artificial lighting than a simple photoresistor.
  • Three I2C addresses are selectable via the ADDR pin (float/GND/VCC) for running multiple units on one bus — TSL2561_ADDR_FLOAT is the default with ADDR left unconnected.
  • enableAutoRange(true) handles both dim and bright conditions without manual gain switching; without it, direct sunlight will saturate the sensor at default gain.
View full Arduino Uno guide

Related