SparkFun Forums 

Where electronics enthusiasts find answers.

Have questions about a SparkFun product or board? This is the place to be.
By jbuehl
#182917
Has anyone been able to get the TSL2561 luminance sensor working with the ESP8266? I have 2 of the Sparkfun TSL2561 breakout boards and neither will work with the ESP8266 Thing using the Sparkfun TSL2561 library. There seem to be a number of people who have gotten this sensor to work with Arduinos, but I can't find any instances of this sensor working with the ESP8266. It seems like it should work, given that it is an I2C device and Sparkfun has designed the Thing board to include one.

I have had a long conversation with Sparkfun tech support and we are still working on it, but I wanted to see if anyone in this forum had tried it.
By Valen
#182933
Did you address it with the right slave address? There are 3 options depending on how the ADDR solderpads are being connected. And then there is the Read/write bit that needs to be added as the lowest significant bit. As you have not shown any of your code it is impossible to help further on this avenue.
By jbuehl
#182942
I didn't have time yesterday to post all the details of what I have tried so I was just asking a quick question if anyone had been successful rather than asking for help. But since you asked... :)

Yes, I am able to address it at the default address of 0x39 and I am seeing the problem with and without the pullup resistors on the breakout board. What I am seeing is that some I2C reads succeed and some fail with an error 2 (NAK).

Here are some snippets of the code I modified in the SparkFun TSL2561 example that I got from here https://github.com/sparkfun/SparkFun_TS ... no_Library to provide more debug information and to add some delays.
Code: Select all
void setup()
{
  Serial.begin(9600);
  Serial.println();
  Serial.println("TSL2561 example sketch");
  light.begin();
  readRegisters();
  unsigned char ID;
  if (light.getID(ID))
  {
    Serial.print("Got factory ID: 0X");
    Serial.print(ID,HEX);
    Serial.println(", should be 0X5X");
  }
  else
  {
    byte error = light.getError();
    printError(error);
  }
  gain = 0;
  unsigned char time = 0;
  Serial.println("Set timing...");
  if(!light.setTiming(gain,time,ms))
  {
    byte error = light.getError();
    printError(error);
  }
  Serial.println("Powerup...");
  if(!light.setPowerUp())
  {
    byte error = light.getError();
    printError(error);
  }
  Serial.println("Done setting up");
}
 
void readRegisters() {
  unsigned char v;
  for (unsigned char i=0; i<16; i++) {
    v = light.readByte(i, v);
    delay(1000);
  }
}

boolean SFE_TSL2561::readByte(unsigned char address, unsigned char &value)
{
    Serial.print("readByte ");
    Serial.print(address, HEX);
    Serial.print(":");
    // Set up command byte for read
    Wire.beginTransmission(_i2c_address);
    Wire.write((address & 0x0F) | TSL2561_CMD);
    _error = Wire.endTransmission();

    // Read requested byte
    if (_error == 0)
    {
        Wire.requestFrom(_i2c_address,1);
                delay(10);
        if (Wire.available() == 1)
        {
            value = Wire.read();
            Serial.print(value, HEX);
            Serial.println();
            return(true);
        }
    }
        Serial.print("error ");
        Serial.print(_error);
        Serial.println();
    return(false);
}
And here's the output.
Code: Select all
TSL2561 example sketch
readByte 0:0
readByte 1:error 2
readByte 2:0
readByte 3:error 2
readByte 4:0
readByte 5:error 2
readByte 6:0
readByte 7:error 2
readByte 8:80
readByte 9:error 2
readByte A:50
readByte B:error 2
readByte C:0
readByte D:error 2
readByte E:0
readByte F:error 2
readByte A:50
Got factory ID: 0X50, should be 0X5X
Set timing...
readByte 1:error 2
I2C error: 2, received NACK on address (disconnected?)
Powerup...
Done setting up
readWord C:137
readWord E:8B
data0: 311 data1: 139 lux: 1474.65 (good)
readWord C:error 2
I2C error: 2, received NACK on address (disconnected?)
readWord C:137
readWord E:8B
data0: 311 data1: 139 lux: 1474.65 (good)
readWord C:error 2
I2C error: 2, received NACK on address (disconnected?)
readWord C:137
readWord E:8C
data0: 311 data1: 140 lux: 1445.71 (good)
.
.
.
More information:

The TSL2561 also fails to work with a Raspberry Pi and an Intel Edison, but in a different way. A byte read from a register always returns the address of the register. This happens both with the i2cget linux command line utility and with the smbus python library on the RPi. Every one of the half dozen other I2C chips I have used on these platforms work flawlessly.
Code: Select all
root@edison:~# i2cdetect -y -r 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- 39 -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
root@edison:~# i2cget -y 1 0x39 0x00
0x00
root@edison:~# i2cget -y 1 0x39 0x0a
0x0a
root@edison:~# i2cdump -y -r 0x00-0x0f 1 0x39 b
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f    .???????????????
I have slowed down the I2C bus on the Raspberry Pi from 100Kb to 10Kb and that had no effect. The ESP8266 runs at 100Kb and the Edison runs at 400Kb but I don't know how to change them, but that chip is supposed to be good up to 400Kb.

I can read data from a TMP102 temperature sensor on the ESP8266 Thing, so the I2C interface and the wire library obviously work.

The only conclusion I can reach is that either this chip has some oddball I2C bus timing requirements or the ones I have are simply defective. I will have access to some test equipment that will let me debug the hardware interface, but that won't happen for a couple of weeks.
By jbuehl
#182949
Problem solved, thanks to Sparkfun tech support.

There is a bug in the TSL2561 library. The line Wire.endTransmission(true); needs to be added after lines 349 and 400 in SparkFunTSL2561.cpp, e.g.
Code: Select all
boolean SFE_TSL2561::readByte(unsigned char address, unsigned char &value)
	// Reads a byte from a TSL2561 address
	// Address: TSL2561 address (0 to 15)
	// Value will be set to stored byte
	// Returns true (1) if successful, false (0) if there was an I2C error
	// (Also see getError() above)
{
	// Set up command byte for read
	Wire.beginTransmission(_i2c_address);
	Wire.write((address & 0x0F) | TSL2561_CMD);
	_error = Wire.endTransmission();

	// Read requested byte
	if (_error == 0)
	{
		Wire.requestFrom(_i2c_address,1);
		if (Wire.available() == 1)
		{
			value = Wire.read();
			Wire.endTransmission(true);
			return(true);
		}
	}
	return(false);
}
This doesn't explain what is going on with the RPi and Edison, but this solves my immediate problem.
User avatar
By Ross Robotics
#182950
Thanks for posting the solution, definitely will help someone in the future.