Home » ESP32 and TSL2591 light-to-digital converter example using the Arduino IDE

ESP32 and TSL2591 light-to-digital converter example using the Arduino IDE

by shedboy71
esp32 and tsl2591 layout

In this article we look at the the TSL2591 which is a light-to-digital converter. We will have the usual information about the sensor, parts list, schematic and code so you can use this sensor.

This is the sensor I bought

First lets look at the sensor

The TSL2591 is a very high sensitivity light-to-digital converter that transforms light intensity into a digital signal output capable of direct I2C interface. The device combines one broadband photodiode (visible plus infrared) and one infrared-responding photodiode on a single CMOS integrated circuit.

Two integrating ADCs convert the photodiode currents into a digital output that represents the irradiance measured on each channel.

This digital output can be input to a microprocessor where illuminance (ambient light level) in lux is derived using an empirical formula to approximate the human eye response. The TSL2591 supports a traditional level style interrupt that remains asserted until the firmware clears it


  • Highest sensitivity to 188µLux
  • Patented dual-diode architecture
  • 600M:1 dynamic range
  • Programmable interrupt function
  • UV-rejection package


Parts Required

The sensor costs about $5 and here are links to the ESP32 board, you will also need some connecting wires

Name Link
Connecting cables
Name Link
ESP32 WeMos Mini D1 LOLIN32 ESP32
TSL2591 TSL2591 Optical Light Sensor Development Board High Dynamic Digital Light Sensor Module
Connecting wire Free shipping Dupont line 120pcs 20cm male to male + male to female and female to female jumper wire


Easy to connect being an I2C sensor

esp32 and tsl2591 layout

esp32 and tsl2591 layout

Code Example

This uses the library from https://github.com/adafruit/Adafruit_TSL2591_Library

This is the default example


/* TSL2591 Digital Light Sensor */
/* Dynamic Range: 600M:1 */
/* Maximum Lux: 88K */

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_TSL2591.h"

// Example for demonstrating the TSL2591 library - public domain!

// connect SCL to I2C Clock
// connect SDA to I2C Data
// connect Vin to 3.3-5V DC
// connect GROUND to common ground

Adafruit_TSL2591 tsl = Adafruit_TSL2591(2591); // pass in a number for the sensor identifier (for your use later)

    Configures the gain and integration time for the TSL2591
void configureSensor(void)
  // You can change the gain on the fly, to adapt to brighter/dimmer light situations
  //tsl.setGain(TSL2591_GAIN_LOW);    // 1x gain (bright light)
  tsl.setGain(TSL2591_GAIN_MED);      // 25x gain
  //tsl.setGain(TSL2591_GAIN_HIGH);   // 428x gain
  // Changing the integration time gives you a longer time over which to sense light
  // longer timelines are slower, but are good in very low light situtations!
  //tsl.setTiming(TSL2591_INTEGRATIONTIME_100MS);  // shortest integration time (bright light)
  // tsl.setTiming(TSL2591_INTEGRATIONTIME_200MS);
  // tsl.setTiming(TSL2591_INTEGRATIONTIME_400MS);
  // tsl.setTiming(TSL2591_INTEGRATIONTIME_500MS);
  // tsl.setTiming(TSL2591_INTEGRATIONTIME_600MS);  // longest integration time (dim light)

  /* Display the gain and integration time for reference sake */  
  Serial.print  (F("Gain:         "));
  tsl2591Gain_t gain = tsl.getGain();
    case TSL2591_GAIN_LOW:
      Serial.println(F("1x (Low)"));
    case TSL2591_GAIN_MED:
      Serial.println(F("25x (Medium)"));
    case TSL2591_GAIN_HIGH:
      Serial.println(F("428x (High)"));
    case TSL2591_GAIN_MAX:
      Serial.println(F("9876x (Max)"));
  Serial.print  (F("Timing:       "));
  Serial.print((tsl.getTiming() + 1) * 100, DEC); 
  Serial.println(F(" ms"));

void setup(void) 
  Serial.println(F("Starting Adafruit TSL2591 Test!"));
  if (tsl.begin()) 
    Serial.println(F("Found a TSL2591 sensor"));
    Serial.println(F("No sensor found ... check your wiring?"));
    while (1);
  /* Configure the sensor */

    Shows how to perform a basic read on visible, full spectrum or
    infrared light (returns raw 16-bit ADC values)
void simpleRead(void)
  // Simple data read example. Just read the infrared, fullspecrtrum diode 
  // or 'visible' (difference between the two) channels.
  // This can take 100-600 milliseconds! Uncomment whichever of the following you want to read
  uint16_t x = tsl.getLuminosity(TSL2591_VISIBLE);
  //uint16_t x = tsl.getLuminosity(TSL2591_FULLSPECTRUM);
  //uint16_t x = tsl.getLuminosity(TSL2591_INFRARED);

  Serial.print(F("[ ")); Serial.print(millis()); Serial.print(F(" ms ] "));
  Serial.print(F("Luminosity: "));
  Serial.println(x, DEC);

    Show how to read IR and Full Spectrum at once and convert to lux
void advancedRead(void)
  // More advanced data read example. Read 32 bits with top 16 bits IR, bottom 16 bits full spectrum
  // That way you can do whatever math and comparisons you want!
  uint32_t lum = tsl.getFullLuminosity();
  uint16_t ir, full;
  ir = lum >> 16;
  full = lum & 0xFFFF;
  Serial.print(F("[ ")); Serial.print(millis()); Serial.print(F(" ms ] "));
  Serial.print(F("IR: ")); Serial.print(ir);  Serial.print(F("  "));
  Serial.print(F("Full: ")); Serial.print(full); Serial.print(F("  "));
  Serial.print(F("Visible: ")); Serial.print(full - ir); Serial.print(F("  "));
  Serial.print(F("Lux: ")); Serial.println(tsl.calculateLux(full, ir), 6);

    Performs a read using the Adafruit Unified Sensor API.
void unifiedSensorAPIRead(void)
  /* Get a new sensor event */ 
  sensors_event_t event;
  /* Display the results (light is measured in lux) */
  Serial.print(F("[ ")); Serial.print(event.timestamp); Serial.print(F(" ms ] "));
  if ((event.light == 0) |
      (event.light > 4294966000.0) | 
      (event.light <-4294966000.0))
    /* If event.light = 0 lux the sensor is probably saturated */
    /* and no reliable data could be generated! */
    /* if event.light is +/- 4294967040 there was a float over/underflow */
    Serial.println(F("Invalid data (adjust gain or timing)"));
    Serial.print(event.light); Serial.println(F(" lux"));

    Arduino loop function, called once 'setup' is complete (your own code
    should go here)
void loop(void) 
  // unifiedSensorAPIRead();




Open the serial monitor and you should see something like this

Starting Adafruit TSL2591 Test!
Found a TSL2591 sensor
Gain: 25x (Medium)
Timing: 300 ms

[ 475 ms ] IR: 397 Full: 931 Visible: 534 Lux: 16.662176
[ 1337 ms ] IR: 461 Full: 1012 Visible: 551 Lux: 16.320053
[ 2199 ms ] IR: 1539 Full: 4068 Visible: 2529 Lux: 85.529442
[ 3061 ms ] IR: 1840 Full: 5609 Visible: 3769 Lux: 137.773529
[ 3923 ms ] IR: 1839 Full: 5611 Visible: 3772 Lux: 137.943741





You may also like

Leave a Comment

Adblock Detected

Please support us by disabling your AdBlocker extension from your browsers for our website.