TSL2561 and Raspberry Pi
Moderators: adafruit_support_bill, adafruit

TSL2561 and Raspberry Pi

by pandring on Sun Dec 02, 2012 5:19 pm

I want to use the TSL2561 with my Raspberry Pi, but your tutorial http://learn.adafruit.com/tsl2561/overview is for Arduino. I assume it's possible to use it with RPi, but I'm fairly new to this and don't know what I would need to do to get it to work with the RPi. What things do I have to do differently from the tutorial to get it to work?
Thanks!
pandring
 
Posts: 25
Joined: Sun Dec 02, 2012 5:15 pm

Re: TSL2561 and Raspberry Pi

by adafruit_support_rick on Wed Dec 12, 2012 12:59 pm

The TSL2561 is a 3.3V I2C device. You would wire it to the Pi the same way you wire it to the arduino - 3.3V, GND, SDA, and SCL.

We have a tutorial for using another I2C device, the BMP085, with the Pi. The wiring and I2C setup on the Pi will be essentially the same. Have a look and see if it gets you started…

http://learn.adafruit.com/using-the-bmp ... i/overview

adafruit_support_rick
 
Posts: 12938
Joined: Tue Mar 15, 2011 11:42 am
Location: Buffalo, NY

Re: TSL2561 and Raspberry Pi

by Static on Sat Dec 15, 2012 8:47 pm

I just ordered one of these to put on my Pi's I2C bus.
I'd like to integrate it into the remote thermal probe I have, but it is probably going to take some time. I'll let you know how it goes.
I gotta warn you, I'm a rank newbie, and my code is going to be dirty.
Static
 
Posts: 180
Joined: Thu Dec 23, 2010 6:21 pm

Re: TSL2561 and Raspberry Pi

by Static on Sun Dec 16, 2012 2:03 am

I had the package delivered to the wrong address. It's going to be a couple of days.
My apologies for the slight threadjack, but if you take a look at the code on the TMP102 issue that I'm having, and see any issues, it will help me with your code as well.
http://forums.adafruit.com/viewtopic.php?f=8&t=35249

I'll let you know as soon as I get a chance to mess with the light sensor.

Static
Static
 
Posts: 180
Joined: Thu Dec 23, 2010 6:21 pm

Re: TSL2561 and Raspberry Pi

by pandring on Tue Jan 15, 2013 7:48 pm

Sorry it's been awhile, I've put this project off as I've had to work on some other ones.

Anyways, I have my RPi and the light sensor wired (and I can detect the sensor at port 0x39), but I can't figure out how to actually get it working. I've tried to read through the code for the TSL2561, but I don't know C++ at all, and it's very unclear what I have to do to read data from the pi.

I understand that I have to use some combinations of the smbus "read_byte" and "write_byte" functions to control and read the light sensor, but I'm not sure what I should be passing the sensor, or how I should be reading it. Can you explain how to setup and read data from the sensor?
Thanks so much!
Peter
pandring
 
Posts: 25
Joined: Sun Dec 02, 2012 5:15 pm

Re: TSL2561 and Raspberry Pi

by adafruit_support_rick on Wed Jan 16, 2013 11:51 am

Actually, you don't want SMBus at all. The TSL2561 uses I2C for communication (the TSL2560 is the SMBus version).

As for setting up and reading data, as you can see from the C++ arduino library, those are non-trivial operations (well, the actual data-transfer using I2C is trivial; knowing what to send and how to interpret the results ... not so much).

The datasheet is really your best bet for understanding how the thing operates. The C++ code is not particularly complex - I think with a little back-and-forth between the datasheet and the code, you ought to be able to figure out what's going on.

adafruit_support_rick
 
Posts: 12938
Joined: Tue Mar 15, 2011 11:42 am
Location: Buffalo, NY

Re: TSL2561 and Raspberry Pi

by pandring on Wed Jan 16, 2013 6:46 pm

That helps a lot! Thanks!

Two questions: In the datasheet there is pseudocode instructing you how to use the sensor. In the code, there are functions readWord, writeWord, readByte, and writeByte. Are those functions equivalent to the ones in the adafruit i2c library? Or do I need to write my own functions?

Also, do you know of a python library I can use to calculate lux? I see that there is code for a C++ function to convert lux, but it would make my life a lot easier if there's a premade python function out there.
pandring
 
Posts: 25
Joined: Sun Dec 02, 2012 5:15 pm

Re: TSL2561 and Raspberry Pi

by adafruit_support_rick on Wed Jan 16, 2013 7:00 pm

They are roughly the same. The adafruit TSL2561 library write8() is equivalent to pseudocode writeByte(), and the library read16() is equivalent to pseudocode readWord().

'address' in the pseudocode is the I2C address of the part, which is saved in the library as _addr, so it's not an argument to the read and write functions.

The pseudocode read functions include arguments for the destination bytes. The adafruit read16 library function returns an unsigned integer instead.

The pseudocode argument 'command' is the same as the adafruit library argument 'reg'.

The adafruit library functions are use the standard Arduino "Wire" library, which actually implements the I2C communications.

adafruit_support_rick
 
Posts: 12938
Joined: Tue Mar 15, 2011 11:42 am
Location: Buffalo, NY

Re: TSL2561 and Raspberry Pi

by pandring on Wed Jan 16, 2013 7:56 pm

The i2c library function I was talking about is written in python for the raspberry pi. (I think it ships with the BMP085). I found it on GitHub and on the list of libraries within Adafruit's RPi WebIDE.

I'm still a little confused on the i2c and SMBus protocols. You said that they're different, but the adafruit python i2c class (see above) uses SMBus.

Also, how would I use the python readU16 function when I need to read 8 bits from two different registers? In the pseudocode it uses one function to read both, but I'm not sure that works with the readU16 function.
Last edited by pandring on Wed Jan 16, 2013 9:55 pm, edited 1 time in total.
pandring
 
Posts: 25
Joined: Sun Dec 02, 2012 5:15 pm

Re: TSL2561 and Raspberry Pi

by adafruit_support_rick on Wed Jan 16, 2013 9:52 pm

Oh, sorry. Yes - that give you equivalent functions to the pseudocode. Don't worry about the high and low destinations in the pseudocode - that's just the way they chose to represent 16-bit operations. You shouldn't have to split them up. Have a look at one of the readU16 in the library - it does this:
Code: Select all | TOGGLE FULL SIZE
      hibyte = self.bus.read_byte_data(self.address, reg)
      result = (hibyte << 8) + self.bus.read_byte_data(self.address, reg+1)

That's the same operation as the pseudocode 16-bit read.

Note that there are both signed and unsigned versions of the read functions.

pandring wrote:Also, do you know of a python library I can use to calculate lux? I see that there is code for a C++ function to convert lux, but it would make my life a lot easier if there's a premade python function out there.

You're referring to the math in the TSL2561 arduino library? That's going to be specific to the data the TSL2561 puts out. But really, it shouldn't be all that difficult to convert the algorithm to python.

adafruit_support_rick
 
Posts: 12938
Joined: Tue Mar 15, 2011 11:42 am
Location: Buffalo, NY

Re: TSL2561 and Raspberry Pi

by pandring on Wed Jan 16, 2013 10:15 pm

I'm pretty confused then... Can you take a look at my code?

Code: Select all | TOGGLE FULL SIZE
from Adafruit_I2C import * ## Code from Github
address = 0x39 ## Device address
control_on = 0x03 ## "On" value
control_off = 0x00 ## "Off" value

i2c = Adafruit_I2C(address)

def enable():
   print "enabling"
   i2c.write8(0x00, control_on) ##Writes on value to control register
   
def disable():
   print "disabling"
   i2c.write8(control, control_off) ##Writes off value to control register
   
def getLight():
   Channel0 = i2c.readU16(0x8C) ## Read total light (from channel 0)
   Channel1 = i2c.readU8(0x8E) ## Read infrared light (from channel 1)
   return Channel0, Channel1

enable()
print getLight()


This code always prints (0, 0), but I'm not sure what I'm doing wrong. I know that there are other calibration functions, but for now I just want to get it working first.
Thanks so much for your help!
pandring
 
Posts: 25
Joined: Sun Dec 02, 2012 5:15 pm

Re: TSL2561 and Raspberry Pi

by adafruit_support_rick on Thu Jan 17, 2013 12:40 pm

Let's go back to the arduino library, and have a look at the enable and disable functions (I left out the "if (!_initialized) begin();"):
Code: Select all | TOGGLE FULL SIZE
void TSL2561::enable(void)
{
  // Enable the device by setting the control bit to 0x03
  write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL, TSL2561_CONTROL_POWERON);
}

void TSL2561::disable(void)
{
  // Disable the device by setting the control bit to 0x03
  write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL, TSL2561_CONTROL_POWEROFF);
}


So, to enable, our register selection will be (TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL). These are constants defined in TSL2561.h:
Code: Select all | TOGGLE FULL SIZE
#define TSL2561_COMMAND_BIT       (0x80)
 . . .
  TSL2561_REGISTER_CONTROL          = 0x00,
 . . .

and the value to write is
Code: Select all | TOGGLE FULL SIZE
#define TSL2561_CONTROL_POWERON   (0x03)


So, the enable command evaluates to
write8(0x80 | 0x00, 0x03);
or
write8(0x80, 0x03);

Disable is
write8(0x80, 0x00);

Now, let's look at getFullLuminosity(). It does this:
Code: Select all | TOGGLE FULL SIZE
  uint32_t x;
  x = read16(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN1_LOW);
  x <<= 16;
  x |= read16(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN0_LOW);

So, it's reading two 16-bit values and stuffing them both into a single 32-bit unsigned integer. Channel 1 goes into the high 16 bits, and channel 0 goes into the low 16 bits.
Substituting the constants, we get
(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN1_LOW) = (0x80 | 0x20 | 0x0E) = (0xAE)
(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN0_LOW) = (0x80 | 0x20 | 0x0C) = (0xAC)
or:
Code: Select all | TOGGLE FULL SIZE
  uint32_t x;
  x = read16(0xAE);
  x <<= 16;
  x |= read16(0xAC);


So, you almost have it right. You missed ORing in the TSL2561_COMMAND_BIT in the enable/disable, and you missed the TSL2561_WORD_BIT in the reads. Also, you want to do a 16-bit read on both channels.

adafruit_support_rick
 
Posts: 12938
Joined: Tue Mar 15, 2011 11:42 am
Location: Buffalo, NY

Re: TSL2561 and Raspberry Pi

by Static on Thu Jan 17, 2013 4:12 pm

pandring,

I tried out your code (with a couple of mods, I'll talk about them in a sec).
Initially I got a reading on the first channel (1792, if it matters). Then, all of my subsequent readings were 0,0

I put in a call to the "disable" function at the end of the code, in case it mattered (I don't know if it does or not). Then I changed the "i2c.write8(control, control_off)" statement to "i2c.write8(0x00, control_off).

Now that I'm looking at it, are we doing this right?
Should both enable and disable functions be writing to 0x39, or the "address" variable (same thing)?

I'm going to keep plugging at this today. I need to get some cleaning done around the house, but I'll definitely be toying with this tonight. If you have any thoughts or steers, please let me know. Thanks.

Static
Static
 
Posts: 180
Joined: Thu Dec 23, 2010 6:21 pm

Re: TSL2561 and Raspberry Pi

by pandring on Thu Jan 17, 2013 8:13 pm

@driverblock,

I changed that in my code, and it works now! I'm able to get a number that will go up when I increase light, and go down when I decrease light. I'm not exactly sure what it is (since we combined our channels, is it visible and infrared light? Or just infrared? Or even just visible?) Now, I just need to get the values into a usable format (i.e. lux). Correct me if I'm wrong, but I assume I should just use the algorithm found on page 22 of the data sheet.
Also, can you explain the difference between the chipscale and TMB formulas? Why should I use one or the other?

Thanks again for all your help!

*UPDATE: Unfortunately, the code's not working anymore! I got two results (251669504 and 16777472), but now it only gives me 0. Is it something about the chip sleeping when inactive?

*UPDATE 2: I just rebooted the RPi, and it seems to be working now...
pandring
 
Posts: 25
Joined: Sun Dec 02, 2012 5:15 pm

Re: TSL2561 and Raspberry Pi

by Static on Thu Jan 17, 2013 8:36 pm

Could you post your revised code when you get a chance?
Also, the data sheet mentions a 400msec delay when the chip is starting up. Could that be the problem?
Static
 
Posts: 180
Joined: Thu Dec 23, 2010 6:21 pm