TSL2591 light-to-digital converter and ESP8266 example

In this article we look at another light-to-digital converter – this time its the TSL2591 and we will connect it to a Wemos Mini

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

Features

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

This is the breakout I bought

Parts Required

Once again for ease of use I connect a Dual Base Shield with a Wemos Mini and then connect the sensor to that as well

Name Link
Wemos Mini WeMos D1 mini
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
Dual Base Shield Double Socket Dual Base Shield for Wemos D1 Mini

 

Schematic/Connection

ESP8266 and TSL2591 layout
ESP8266 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
  tsl.setTiming(TSL2591_INTEGRATIONTIME_300MS);
 
 
  /* Display the gain and integration time for reference sake */  
  Serial.println(F("------------------------------------"));
  Serial.print  (F("Gain:         "));
  tsl2591Gain_t gain = tsl.getGain();
  switch(gain)
  {
    case TSL2591_GAIN_LOW:
      Serial.println(F("1x (Low)"));
      break;
    case TSL2591_GAIN_MED:
      Serial.println(F("25x (Medium)"));
      break;
    case TSL2591_GAIN_HIGH:
      Serial.println(F("428x (High)"));
      break;
    case TSL2591_GAIN_MAX:
      Serial.println(F("9876x (Max)"));
      break;
  }
  Serial.print  (F("Timing:       "));
  Serial.print((tsl.getTiming() + 1) * 100, DEC); 
  Serial.println(F(" ms"));
  Serial.println(F("------------------------------------"));
  Serial.println(F(""));
}
 
 
/**************************************************************************/
/*
    Program entry point for the Arduino sketch
*/
/**************************************************************************/
void setup(void) 
{
  Serial.begin(9600);
 
  Serial.println(F("Starting Adafruit TSL2591 Test!"));
 
  if (tsl.begin()) 
  {
    Serial.println(F("Found a TSL2591 sensor"));
  } 
  else 
  {
    Serial.println(F("No sensor found ... check your wiring?"));
    while (1);
  }
 
  /* Configure the sensor */
  configureSensor();
 
  // Now we're ready to get readings ... move on to loop()!
}
 
/**************************************************************************/
/*
    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;
  tsl.getEvent(&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)"));
  }
  else
  {
    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) 
{ 
  //simpleRead(); 
  advancedRead();
  // unifiedSensorAPIRead();
 
  delay(500);
}

Output

Open the serial monitor and you should see something like this

[ 59978 ms ] IR: 1963 Full: 6330 Visible: 4367 Lux: 163.893448
[ 60840 ms ] IR: 1826 Full: 5850 Visible: 4024 Lux: 150.577118
[ 61703 ms ] IR: 182 Full: 353 Visible: 171 Lux: 4.506262
[ 62565 ms ] IR: 217 Full: 455 Visible: 238 Lux: 6.772381
[ 63427 ms ] IR: 2002 Full: 6302 Visible: 4300 Lux: 159.609024
[ 64289 ms ] IR: 1988 Full: 6319 Visible: 4331 Lux: 161.483032
[ 65152 ms ] IR: 1986 Full: 6317 Visible: 4331 Lux: 161.534180

Links

https://ams.com/tsl25911

 

 

LEAVE A REPLY

Please enter your comment!
Please enter your name here

*