Impossible to get data from TSL2591

Hi guys,

First time posting, not really sure if this is supposed to go here or in I2C topic.
I got a TSL2591 lux sensor a few days ago, soldered it and tried it with Adafruit's library example sketch. But I can't get any data from it, and I'm out of ideas.

Here is a picture of the wiring set up:


Nothing fancy: sensor is alimented by the 5V output of the Arduino, the SCL is connected on the A5 pin and SDA on A4 (and GND to GND! 8) )

And here is the code I use, which is the exact same one as the library example sketch:

/* 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 analog 5
// connect SDA to analog 4
// 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("------------------------------------");
  Serial.print  ("Sensor:       "); Serial.println(sensor.name);
  Serial.print  ("Driver Ver:   "); Serial.println(sensor.version);
  Serial.print  ("Unique ID:    "); Serial.println(sensor.sensor_id);
  Serial.print  ("Max Value:    "); Serial.print(sensor.max_value); Serial.println(" lux");
  Serial.print  ("Min Value:    "); Serial.print(sensor.min_value); Serial.println(" lux");
  Serial.print  ("Resolution:   "); Serial.print(sensor.resolution); Serial.println(" lux");  
  Serial.println("------------------------------------");
  Serial.println("");
  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("------------------------------------");
  Serial.print  ("Gain:         ");
  tsl2591Gain_t gain = tsl.getGain();
  switch(gain)
  {
    case TSL2591_GAIN_LOW:
      Serial.println("1x (Low)");
      break;
    case TSL2591_GAIN_MED:
      Serial.println("25x (Medium)");
      break;
    case TSL2591_GAIN_HIGH:
      Serial.println("428x (High)");
      break;
    case TSL2591_GAIN_MAX:
      Serial.println("9876x (Max)");
      break;
  }
  Serial.print  ("Timing:       ");
  Serial.print((tsl.getTiming() + 1) * 100, DEC); 
  Serial.println(" ms");
  Serial.println("------------------------------------");
  Serial.println("");
}


/**************************************************************************/
/*
    Program entry point for the Arduino sketch
*/
/**************************************************************************/
void setup(void) 
{
  Serial.begin(9600);
  
  Serial.println("Starting Adafruit TSL2591 Test!");
  
  if (tsl.begin()) 
  {
    Serial.println("Found a TSL2591 sensor");
  } 
  else 
  {
    Serial.println("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("[ "); Serial.print(millis()); Serial.print(" ms ] ");
  Serial.print("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("[ "); Serial.print(millis()); Serial.print(" ms ] ");
  Serial.print("IR: "); Serial.print(ir);  Serial.print("  ");
  Serial.print("Full: "); Serial.print(full); Serial.print("  ");
  Serial.print("Visible: "); Serial.print(full - ir); Serial.print("  ");
  Serial.print("Lux: "); Serial.println(tsl.calculateLux(full, ir));
}

/**************************************************************************/
/*
    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("[ "); Serial.print(event.timestamp); Serial.print(" 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("Invalid data (adjust gain or timing)");
  }
  else
  {
    Serial.print(event.light); Serial.println(" lux");
  }
}


/**************************************************************************/
/*
    Arduino loop function, called once 'setup' is complete (your own code
    should go here)
*/
/**************************************************************************/
void loop(void) 
{ 
  //simpleRead(); 
  advancedRead();
  // unifiedSensorAPIRead();
  
  delay(500);
}

And when I try it, the serial monitor displays:

Starting Adafruit TSL2591 Test!
No sensor found ... check your wiring?

Si I spent some time testing everything and looking on the web to find the root of the problem (no success). Now, I am sure the problem does not come from:

  • the wires
  • the Arduino pins (I have a BMP180 that I also plug on A4/A5 with I2C protocol, and it works just fine)
  • the breadboard

I have also measured voltage between the pins of the TSL2591 board: everything seems to be normal, I get around 4.5-5V between SDA and GND as well as between SCL and GND.

So I guess there are two options: either there is a problem is in the code, or the sensor is somehow not sending data (though I get some voltage on SDA).

I have not seen any problem in the code, I even took a look in the library (though I am a beginner in C++). After looking around on the web, I have not found anyone sharing or reporting a similar problem using the example sketch of the library.

As for the sensor itself, well, I really don't know how to tell if it is just dead or something? How can I be sure I just got a defective sensor?

Any help would be really appreciated!

Thanks

sensor is alimented by the 5V output of the Arduino, the SCL is connected on the A5 pin and SDA on A4.

Did you connect the grounds?

Try the I2C Scanner program. If it does not report device present, there is a problem with the wiring or the device itself.

Did you connect the grounds?

Yes, of course! I edited my post so there is no doubt about that.

Try the I2C Scanner program. If it does not report device present, there is a problem with the wiring or the device itself.

Thank you for the advice. I just tried it, and it works: the TSL2591 is found (0x29).

I2C Scanner
Scanning...
I2C device found at address 0x29  !
done

So I guess the problem is in the code?

Image embedded for our convenience:

Technique described here.

I wonder if the wires are too long for the default 100KHz clock speed? Here is a multii-speed I2C scanner you might try. It will tell you which speeds worked, if wire length is the problem. Or you could try shorter wires. :slight_smile:

Cheers,
/dev

Thank you for the suggestion.

TIME	DEC	HEX		50	100	200	250	400	500	800	[KHz]
------------------------------------------------------------------------------------------------
5157	41	0x29		V	V	V	V	V	V	V

1 devices found in 141 milliseconds.

So it seems to work fine with all clock speeds. I also tried with shorter wires, but no change!

I2C requires 4k7 pullup resistors on SDA and SCL. If the board doesn't have them, you'll need to add them to the breadboard.

Pete

I2C requires 4k7 pullup resistors on SDA and SCL. If the board doesn't have them, you'll need to add them to the breadboard.

Thank you for your suggestion.

It is quite unclear from the datasheet, but the Adafruit tutorial use no pullup resistors... so I guess there are on the board?

I still followed your suggestion and added 4.7k pullup resistors on SDA and SCL, but no changes so far :-\

The Adafruit schematic shows a pair of 10k resistors with a FET between them on each of SDA and SCL. I presume that it is sufficient since, as you say, their tutorial doesn't use them. Also, the scanner found the address so that part is working OK.

Pete

The only reason that tsl.begin() will return false is if the sensor does not return a device ID of 0x50.
You could modify the Adafruit library so that you can see what it is returning.
Edit Adafruit_TSL2591.cpp. Starting at line 83 is the if statement which checks the value of the ID. Change it to this:

  if (id == 0x50 )
  {
     // Serial.println("Found Adafruit_TSL2591");
  }
  else
  {
    Serial.print("ERROR: id = ");
    Serial.println(id);
    return false;
  }

Pete

Your setup looks correct, and if you are running the unaltered sketch from the Examples > Adafruit TSL 2591 Library > tsl2591 menu, then you should be seeing numbers scrolling on your serial monitor window. As you are seeing an error, let's assume this means there is no problem with the software, but a major problem with the hardware.

First, eliminate your Arduino, breadboard and wires as suspects. The breadboard would be my first suspect! If you have another one, try it, or just flip the one you have around and use the other side. The next thing to try is to attach a different kind of !2C device using the same wires, breadboard and Arduino. If it doesn't work either, swap out all the wires. Still not work? Try a different Arduino, or, before you do that, try the (unmarked) SDA and SCL on the opposite corner of the board. Any pinout diagram will identify them.

Having eliminated all of your hardware as suspects, the culprit MUST be the TSL2591 breakout board, or some component on it. In that case you should contact Adafruit (assuming you bought it from them) to arrange an exchange.

ps, I just bought a tsl2591 board last week, and it works as advertised.