Using two TSL2561 sensors on one Arduino

Hello,
I am trying to get readings from two TSL2561 (Adafruit Flora) sensors connected to the same Arduino at once.
I have looked on the forum but I've only found dead ends and one code that partially works for me.

The sensors are soldered in line and connected to an Arduino Uno.

The following code gives me the most realistic readings, but it is not stable. The first readings are good, then I will soon get Sensor Overloads on the serial monitor followed by alternating unrealistic readings:

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_TSL2561_U.h>

Adafruit_TSL2561_Unified tsl1 = Adafruit_TSL2561_Unified(TSL2561_ADDR_FLOAT, 12345);
Adafruit_TSL2561_Unified tsl2 = Adafruit_TSL2561_Unified(TSL2561_ADDR_FLOAT, 67890);

void displaySensorDetails(void)
{
  sensor_t sensor;
  tsl1.getSensor(&sensor);
  tsl2.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);
}

void configureSensor(void)
{
  tsl2.enableAutoRange(true);
  tsl2.setIntegrationTime(TSL2561_INTEGRATIONTIME_13MS); 
  Serial.print  ("Gain:         "); Serial.println("Auto");
  Serial.print  ("Timing:       "); Serial.println("13 ms");
  Serial.println("------------------------------------");
}


void setup(void) 
{
  Serial.begin(9600);
  Serial.println("Light Sensor Test"); Serial.println("");
  
  if(!tsl1.begin()){
    Serial.print("Ooops, Sensor 1 TSL2561 not detected ... Check your wiring or I2C ADDR!");
    while(1);
  }
    if(!tsl2.begin()){
    Serial.print("Ooops, Sensor 2 TSL2561 not detected ... Check your wiring or I2C ADDR!");
    while(1);
  }
  
  displaySensorDetails();
  
  configureSensor();

}

void loop(void) 
{  
  /* Get a new sensor event */ 
  sensors_event_t event;
  tsl1.getEvent(&event);
  /* Display results*/
  if (event.light)
  {
    Serial.print("Sensor 1: ");Serial.print(event.light); Serial.println(" lux");
    delay(500);
  }

     tsl2.getEvent(&event);
     if (event.light)
  {
    Serial.print("Sensor 2: ");Serial.print(event.light); Serial.println(" lux");
    delay(500);
  }
   

  else
  {
    /* If event.light = 0 lux the sensor is probably saturated
       and no reliable data could be generated! */
    Serial.println("Sensor overload");
  }

}

I have also tried the code found in this forum at: TSL2561 Luminosity Sensor - Programming Questions - Arduino Forum. However, I get the same results. It starts well and then the readings for pear-shaped.

My question is: is the code the problem?
or is it they way that the sensors are wired (no resistors, no level shifting, etc.), just plain in line.

I would really appreciate any help as I don't know where to look anymore on solving this problem.
Thanks in advance!

In displaySensorDetails()

  sensor_t sensor;
  tsl1.getSensor(&sensor);
  tsl2.getSensor(&sensor);

you are asking to store the data of both sensors into the same variable, over writting the first sensor value with the second one

configureSensor() is only configuring one sensor

Probably good for you to read this and especially that part

Disabling the I2C pullup resistors (PU)

The TSL2561 communicates with a host microcontroller via a communications standard called “I2C” (for Inter-Integrated-Circut). I2C uses two wires, usually labeled SCL (Serial Clock) and SDA (Serial Data). To function properly, I2C requires a pullup resistor on each of those lines. The TSL2561 Breakout Board includes these resistors. They’re enabled by default, but you can disable them by clearing the solder jumper labeled PU.

I2C allows you to have multiple devices connected to the same two lines (collectively called a bus). The pullup resistors allow the bus to function, but you should only have one set of pullup resistors per bus.

If you have just one I2C device (such as the TSL2561 Breakout Board) connected to your microcontroller, the board is already set up properly. You don’t need to change anything.

However, if you wish to connect more than one device to the bus, you should ensure that there is only one set of pullup resistors enabled on the bus. You do this by disabling every set of pullup resistors except one. (It doesn’t matter where the enabled resistors live; they can be anywhere on the bus.)

To disable the I2C pullup resistors, remove all of the solder from the jumper labeled “PU”. This jumper has three pads; be sure to separate all of the pads from each other. Remember that you’ll need to ensure that another set of pullup resistors are enabled somewhere on the I2C bus.

To enable the I2C pullup resistors (factory default), add solder to bridge both sides of the “PU” jumper to the center pad. There should be one large blob of solder when you’re done. Remember that you should only have one set of pullup resistors enabled on the entire I2C bus.

Note that you should not operate an I2C bus without pullup resistors. Aside from not functioning properly, the internal weak pull-up resistors in a 5V Arduino will pull the bus to 5V which may damage the TSL2561.

Changing the I2C address (ADDR)

Every component attached to an I2C bus has a fixed address from 0 to 127. You can theoretically have a maximum of 128 devices on a single bus, but in practice you are limited to the options available for each part.

The TSL2561 supports three possible addresses: 0x29, 0x39, or 0x49. Practically speaking, this means you can have up to three TSL2561s attached to a single I2C bus.

Which address the part uses is controlled by the solder jumper labeled “ADDR”. When there is no solder on this jumper, the TSL2561 will used the default address of 0x39.

To use one of the other addresses, add solder to bridge the center pad to ONE of the two side pads. If you bridge to the “0” side, the address will be 0x29. If you bridge to the “1” side, the address will be 0x49. Don’t bridge both sides.

Correction - if you use adafruit one that's their tutorial for their library

You still need different I2C addresses as they say in the wiring section

The ADDR pin can be used if you have an i2c address conflict, to change the address. Connect it to ground to set the address to 0x29, connect it to 3.3V (vcc) to se t the address to 0x49 or leave it floating (unconnected) to use address 0x39.

If you look at the .h in the library you will see a definition for the possible adresses

...
// I2C address options
#define TSL2561_ADDR_LOW          (0x29)
#define TSL2561_ADDR_FLOAT        (0x39)    // Default address (pin left floating)
#define TSL2561_ADDR_HIGH         (0x49)
...

But in your code you declare both sensors at the 'pin floating address'

Adafruit_TSL2561_Unified tsl1 = Adafruit_TSL2561_Unified([color=red]TSL2561_ADDR_FLOAT[/color], 12345);
Adafruit_TSL2561_Unified tsl2 = Adafruit_TSL2561_Unified([color=red]TSL2561_ADDR_FLOAT[/color], 67890);

If you did not change the wiring for the address both sensors are recognizing that address and try to speak on the I2C bus creating a mess

Thanks for all that.
I would just like to point out that the Adfruit Flora sensors do not have a pins labelled ADDR and therefore, being a newbie, I got confused when I first read the text you post above. They come with Ground, Voltage and 2 sets of SDA/SCL. Perhaps one of these is the ADDR? If so, pardon my ignorance!

Again, thank you. I will look through all the information now to correct the code... and try to figure out how to proceed with the sensor ADDRs. Or I might have to end up getting other sensors.

OK - well the doc then is clear

The sensor has a digital (I2C) interface. Attaching it to the flora is simple: line up the sensor so its adjacent to the SDA/SCL pins and sew conductive thread from the 3V, SDA, SCL and GND pins. They line up perfectly so you will not have any crossed lines. You can only connect one lux sensor to your Flora, but you can connect other I2C sensors/outputs by using the set of SCL/SDA pins on the opposite side. The current draw is extremely low, about 0.5mA when actively sensing, and less than 15 uA when in powerdown mode.

--> seems there is no way to set a different I2C address for this unit

if you want to understand more about I2C addresses you can watch this

So you want two I2C devices with the same address --> you can find ways to connect 2 separate I2C bus to your Arduino. there are components doing this such as the PCA9543A2-Channel I2C Bus Switch (exists with 4 channels PCA9544A I2C Multiplexer IC)

The device does support two addresses. There appears to be a solder jumper to let you select whether it is tied high or low. It's the three squares on the bottom of the board.

CrossRoads:
The device does support two addresses. There appears to be a solder jumper to let you select whether it is tied high or low. It's the three squares on the bottom of the board.

Right - I made the wrong assumption based on the fact they stated "only one"... the web page does state

This board/chip uses I2C 7-bit addresses 0x39, 0x29, 0x49, selectable with jumpers.

--> so just set 2 different addresses and you should be good to go (probably need to worry about I2C pullup resistors)

Thank you both so much!

I have set up 2 TSL2561 now with pull-up resistors and it is working a treat (I jumped the solder to - on one and set the address to LOW). I should think that I can add another, jumping the solder to + (HIGH and LOW, and leave one unsoldered on FLOAT).
I'll attempt to complete the setup with a different light sensor (that might use a different address?). Or look into the bus that JML suggests so I can get the 4th sensor into it.

As a side note, this set up also works without the resistors. I'm only using 1K (when I do) as they were unresponsive with 10K and I have nothing on me in between.

Good job! Congrats & have fun