Data read issue from TSL 2591 Digital light sensor

Hi guys.
It is my first post, and I am a newbie in Arduino, so sorry for any silly questions.

I use Arduino UNO Wi-Fi Rev2 with TSL2591 (lib for TSL2591) to check the correctness of the brightness values on the LCD. Here are the details:

  1. Connection schematic - (Photo Schematic)
  2. I fixed the sensor inside a dark plastic bottle and placed it near the screen - (Photo Container)
  3. My code:
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_TSL2591.h"

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


void setup() {
  Serial.begin(9600);
  //tsl.setGain(TSL2591_GAIN_MED);
  tsl.setGain(TSL2591_GAIN_HIGH);
  tsl.setTiming(TSL2591_INTEGRATIONTIME_300MS);

}

void loop(void)
{
  uint16_t sens;
  int valueLight;
  if (Serial.available() > 0)
  {
    valueLight = Serial.parseInt();
    Serial.read();
    sens = tsl.getLuminosity(TSL2591_VISIBLE);
    Serial.println(sens & 0xFFFF, DEC);

    switch (valueLight)
    {
      case 12:
        if (sens > 1 && sens < 50)
        {
          Serial.println("SCREEN OFF: PASSED");

        } else if (sens > 51 && sens < 100)
        {
          Serial.println("ERROR: THE BACKLIGHT WORKS!");
        }
        else
        {
          Serial.println("SCREEN OFF: FAILED");
        }
        break;
      case 11:
        if (sens > 51 && sens < 10000)
        {
          Serial.println("SCREEN ON: PASSED");

        } else if (sens > 51 && sens < 100)
        {
          Serial.println("ERROR: THE SYSTEM DOES NOT RUN!");
        }
        else
        {
          Serial.println("SCREEN ON: FAILED");
        }
        break;
      case 10:
        if (sens > 6620 && sens < 6645)
        {
          Serial.println("BRIGHTNESS_100: PASSED");
        }
        else
        {
          Serial.println("BRIGHTNESS_100: FAILED");
        }
        break;
      case 9:
        if (sens > 5465 && sens < 5495)
        {
          Serial.println("BRIGHTNESS_90: PASSED");
        }
        else
        {
          Serial.println("BRIGHTNESS_90: FAILED");
        }
        break;
      case 8:
        if (sens > 4410 && sens < 4435)
        {
          Serial.println("BRIGHTNESS_80: PASSED");
        }
        else
        {
          Serial.println("BRIGHTNESS_80: FAILED");
        }
        break;
      case 7:
        if (sens > 3485 && sens < 3515)
        {
          Serial.println("BRIGHTNESS_70: PASSED");
        }
        else
        {
          Serial.println("BRIGHTNESS_70: FAILED");
        }
        break;
      case 6:
        if (sens > 2790 && sens < 2820)
        {
          Serial.println("BRIGHTNESS_60: PASSED");
        }
        else
        {
          Serial.println("BRIGHTNESS_60: FAILED");
        }
        break;
      case 5:
        if (sens > 2215 && sens < 2250)
        {
          Serial.println("BRIGHTNESS_50: PASSED");
        }
        else
        {
          Serial.println("BRIGHTNESS_50: FAILED");
        }
        break;
      case 4:
        if (sens > 1425 && sens < 1455)
        {
          Serial.println("BRIGHTNESS_40: PASSED");
        }
        else
        {
          Serial.println("BRIGHTNESS_40: FAILED");
        }
        break;
      case 3:
        if (sens > 835 && sens < 865)
        {
          Serial.println("BRIGHTNESS_30: PASSED");
        }
        else
        {
          Serial.println("BRIGHTNESS_30: FAILED");
        }
        break;
      case 2:
        if (sens > 230 && sens < 265)
        {
          Serial.println("BRIGHTNESS_20: PASSED");
        }
        else
        {
          Serial.println("BRIGHTNESS_20: FAILED");
        }
        break;
      case 1:
        if (sens > 385 && sens < 405)
        {
          Serial.println("BRIGHTNESS_10: PASSED");
        }
        else
        {
          Serial.println("BRIGHTNESS_10: FAILED");
        }
        break;
      case 0:
        if (sens > 95 && sens < 115)
        {
          Serial.println("BRIGHTNESS_0: PASSED");
        }
        else
        {
          Serial.println("BRIGHTNESS_0: FAILED");
        }
        break;
      case 30:
        if (sens > 142 && sens < 168)
        {
          Serial.println("BACKLIGHT_70: PASSED");
        }
        else
        {
          Serial.println("BACKLIGHT_70: FAILED");
        }
        break;
      case 29:
        if (sens > 100 && sens < 105)
        {
          Serial.println("BACKLIGHT_90: PASSED");
        }
        else
        {
          Serial.println("BACKLIGHT_90: FAILED");
        }
        break;
      case 28:
        if (sens > 100 && sens < 105)
        {
          Serial.println("BACKLIGHT_80: PASSED");
        }
        else
        {
          Serial.println("BACKLIGHT_80: FAILED");
        }
        break;
      case 27:
        if (sens > 100 && sens < 105)
        {
          Serial.println("BACKLIGHT_70: PASSED");
        }
        else
        {
          Serial.println("BACKLIGHT_70: FAILED");
        }
        break;
      case 26:
        if (sens > 100 && sens < 105)
        {
          Serial.println("BACKLIGHT_60: PASSED");
        }
        else
        {
          Serial.println("BACKLIGHT_60: FAILED");
        }
        break;
      case 25:
        if (sens > 100 && sens < 105)
        {
          Serial.println("BACKLIGHT_50: PASSED");
        }
        else
        {
          Serial.println("BACKLIGHT_50: FAILED");
        }
        break;
      case 24:
        if (sens > 100 && sens < 105)
        {
          Serial.println("BACKLIGHT_40: PASSED");
        }
        else
        {
          Serial.println("BACKLIGHT_40: FAILED");
        }
        break;
      case 23:
        if (sens > 100 && sens < 105)
        {
          Serial.println("BACKLIGHT_30: PASSED");
        }
        else
        {
          Serial.println("BACKLIGHT_30: FAILED");
        }
        break;
      case 22:
        if (sens > 100 && sens < 105)
        {
          Serial.println("BACKLIGHT_20: PASSED");
        }
        else
        {
          Serial.println("BACKLIGHT_20: FAILED");
        }
        break;
      case 21:
        if (sens > 100 && sens < 105)
        {
          Serial.println("BACKLIGHT_10: PASSED");
        }
        else
        {
          Serial.println("BACKLIGHT_10: FAILED");
        }
        break;
      case 20:
        if (sens > 100 && sens < 105)
        {
          Serial.println("BACKLIGHT_0: PASSED");
        }
        else
        {
          Serial.println("BACKLIGHT_0: FAILED");
        }
        break;
      default:
        break;
    }
  }
  delay(500);
}

Previously, I checked the sensor values on all brightness values (100, 90, 80, .... 0) and described the range of sensor values in switch cases. So, the logic of the sketch is as follows

  1. Set up brightness value on the screen.
  2. Send command to the serial port.
  3. Get result - if real sensor values match with previously written values - the result is passed, if it doesn't match - failed.
    I am facing a problem - after a while, or as a result of disconnecting the Arduino from the power supply, or re-uploading sketch, the sensor shows different values from those that I wrote down earlier, under the same external conditions.
    For testing the problem, I uploaded the standard TSL2591 sketch and checked values for 1 hour. Sensor readings are constantly rising or falling like this:
2214
2214
2214
2213
2213
.........
2190
.........
2140

If remove the sensor from the screen, and then put it again the value becomes correct, but still rising or falling.
Note 1
If I use a simple sketch to display entered values:

void loop(void) // full code
  if (Serial.available() > 0)
  {  
      int data = Serial.parseInt();
      Serial.println(data);
  }  
}

My Arduino prints entered value and then 0 like this:

45
0
78
0
45
0

Also, I found some oddities

  1. In the standard TSL sketch, in Void Setup(void) described connection check of a sensor.
/* 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)

/**************************************************************************/
/*
    Displays some basic information on this sensor from the unified
    sensor API sensor_t type (see Adafruit_Sensor for more information)
*/
/**************************************************************************/
void displaySensorDetails(void)
{
  sensor_t sensor;
  tsl.getSensor(&sensor);
  Serial.println(F("------------------------------------"));
  Serial.print  (F("Sensor:       ")); Serial.println(sensor.name);
  Serial.print  (F("Driver Ver:   ")); Serial.println(sensor.version);
  Serial.print  (F("Unique ID:    ")); Serial.println(sensor.sensor_id);
  Serial.print  (F("Max Value:    ")); Serial.print(sensor.max_value); Serial.println(F(" lux"));
  Serial.print  (F("Min Value:    ")); Serial.print(sensor.min_value); Serial.println(F(" lux"));
  Serial.print  (F("Resolution:   ")); Serial.print(sensor.resolution, 4); Serial.println(F(" lux"));
  Serial.println(F("------------------------------------"));
  Serial.println(F(""));
  delay(500);
}

/**************************************************************************/
/*
    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_300MS);
  // 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.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);
  }

  /* Display some basic information on this sensor */
  displaySensorDetails();

  /* 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);
}

Even if I disconnect the sensor, my Arduino print:

Starting Adafruit TSL2591 Test!
Found a TSL2591 sensor
  1. I used Speed I2C Scanner to check the wires. And it shows, that connected two devices to I2C
TIME DEC HEX   50 100 150 200 250 300 350 400 [KHz]
12320 40 0x28   .  .   .   .   .   .   .   .
12323 41 0x29   V  V   V   V   V   V   V   V
12326 42 0x2A   .  .   .   .   .   .   .   .
.............
12471 94 0x5E   .      .       .       .       .        .       .        .
12474 95 0x5F   .  .   .   .   .   .   .    .
12477 96 0x60   V  V   V   V   V   V   V    V
12479 97 0x61   .  .   .   .   .   .   .    .
2 devices found in 322 milliseconds.
  1. If connect the TSL2891 to analog A4(SDA) and A5(SCL) the sensor does not found. In serial output - 65535

I will be very happy, if you can try to solve this problem or suggest other options for implementing the sketch.
Thanks in advance.

Thanks for using code tags on your first post!

However, please edit your post to attach images directly, and link them within the post. Use the post editor preview and upload files buttons.

Always post ALL the code. Enter CTRL-T in the Arduino IDE to format and indent the code, then select/copy/paste directly to avoid the "[ color=#222222]" nonsense. Do not use "copy for forum" or "html".

Finally, post a link to the product page for the exact TSL2591 module you have.

A much simpler standalone program to collect raw data from the TSL2591 can be found here.

jremington:
Thanks for using code tags on your first post!

However, please edit your post to attach images directly, and link them within the post. Use the post editor preview and upload files buttons.

Always post ALL the code. Enter CTRL-T in the Arduino IDE to format and indent the code, then select/copy/paste directly to avoid the "[ color=#222222]" nonsense. Do not use "copy for forum" or "html".

Finally, post a link to the product page for the exact TSL2591 module you have.

A much simpler standalone program to collect raw data from the TSL2591 can be found here.

Thanks for your remarks, I hope I edited my post correctly.

Sensor readings are constantly rising or falling like this:

Looks like normal sensor noise/variation to me.

My Arduino prints entered value and then 0 like this:

Check the line ending setting on the Serial monitor input (no line ending, newline, etc.).

Even if I disconnect the sensor, my Arduino print: ... Found a TSL2591 sensor

This suggests a serious problem with the library, or possibly an I2C address conflict with another device. Run the I2C scanner AGAIN, with the TSL2591 removed. My code checks for the correct device ID.

And it shows, that connected two devices to I2C

Maybe the second is the WiFi.

I fixed the sensor inside a dark plastic bottle and placed it near the screen

For low light levels, the LED on the sensor is a problem. You should remove it, or remove the current limiting resistor next to it.

If connect the TSL2891 to analog A4(SDA) and A5(SCL) the sensor does not found. In serial output - 65535

On an Uno (I don't know about the Uno Wifi), A4 and A5 are the same connections as SDA and SCL (internally connected on the board). Check your wiring carefully. Note: I2C is designed for communications between ICs on a single circuit board, and you will likely have problems with a wired connection longer than a few cm.

jremington:
For low light levels, the LED on the sensor is a problem. You should remove it, or remove the current limiting resistor next to it.

I know Adafruit redesigned the TSL2591 breakout to add a stemma connector ... but did they really add an LED? That would be a dumb thing to do on a photo sensor of this level of sensitivity....!
S.

That would be a dumb thing to do on a photo sensor of this level of sensitivity....!

Yes, amazingly thoughtless. The LED is very bright.

In looking at the product description, I just now noticed that a cuttable jumper was recently added to the back of the board to disable the LED.

LED and 10K current limiting resistor outlined in red below:

tsl2591.png

tsl2591.png

jremington:
Yes, amazingly thoughtless. The LED is very bright.

Extraordinary. Thanks for pointing this out, and the jumper fix. It is something I will keep in mind, though I have a couple of the older boards on hand which will hopefully serve my needs for some time.
S.

jremington:
Looks like normal sensor noise/variation to me.
Check the line ending setting on the Serial monitor input (no line ending, newline, etc.).
This suggests a serious problem with the library, or possibly an I2C address conflict with another device. Run the I2C scanner AGAIN, with the TSL2591 removed. My code checks for the correct device ID.
Maybe the second is the WiFi.
For low light levels, the LED on the sensor is a problem. You should remove it, or remove the current limiting resistor next to it.
On an Uno (I don't know about the Uno Wifi), A4 and A5 are the same connections as SDA and SCL (internally connected on the board). Check your wiring carefully. Note: I2C is designed for communications between ICs on a single circuit board, and you will likely have problems with a wired connection longer than a few cm.

Thanks for your advice)
I will check your recommendation.

jremington:
Looks like normal sensor noise/variation to me.
Check the line ending setting on the Serial monitor input (no line ending, newline, etc.).
This suggests a serious problem with the library, or possibly an I2C address conflict with another device. Run the I2C scanner AGAIN, with the TSL2591 removed. My code checks for the correct device ID.
Maybe the second is the WiFi.
For low light levels, the LED on the sensor is a problem. You should remove it, or remove the current limiting resistor next to it.
On an Uno (I don't know about the Uno Wifi), A4 and A5 are the same connections as SDA and SCL (internally connected on the board). Check your wiring carefully. Note: I2C is designed for communications between ICs on a single circuit board, and you will likely have problems with a wired connection longer than a few cm.

  1. Now I'm testing the data from the sensor to determine sensor error.
  2. Yes, it's really help, thank you.
  3. I don't know why Arduino print that. ID of disconnected sensor the same as ID connected sensor.
  4. I found that on UNO Wi-Fi Rev2 pins A4/A5 busy by ATECC608A (It is a built in device on this board). And for I2C connection I should use SDA/SCL pins.
  5. My sensor is missing an LED, it doesn't problem for my project.
  6. For complete confidence, I cut the length of the wires thank you.

This is the problem of TSL calculation. I changed sensor on BH1750 and it works fine. Thanks for all.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.