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!
TSL2561 and Raspberry Pi
Moderators: adafruit_support_bill, adafruit
Please be positive and constructive with your questions and comments.
- adafruit_support_rick
- Posts: 35092
- Joined: Tue Mar 15, 2011 11:42 am
Re: TSL2561 and Raspberry Pi
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
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
- static
- Posts: 188
- Joined: Thu Dec 23, 2010 6:21 pm
Re: TSL2561 and Raspberry Pi
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.
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: 188
- Joined: Thu Dec 23, 2010 6:21 pm
Re: TSL2561 and Raspberry Pi
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
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
-
- Posts: 25
- Joined: Sun Dec 02, 2012 5:15 pm
Re: TSL2561 and Raspberry Pi
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
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
- adafruit_support_rick
- Posts: 35092
- Joined: Tue Mar 15, 2011 11:42 am
Re: TSL2561 and Raspberry Pi
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.
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.
-
- Posts: 25
- Joined: Sun Dec 02, 2012 5:15 pm
Re: TSL2561 and Raspberry Pi
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.
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.
- adafruit_support_rick
- Posts: 35092
- Joined: Tue Mar 15, 2011 11:42 am
Re: TSL2561 and Raspberry Pi
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.
'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.
-
- Posts: 25
- Joined: Sun Dec 02, 2012 5:15 pm
Re: TSL2561 and Raspberry Pi
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.
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.
- adafruit_support_rick
- Posts: 35092
- Joined: Tue Mar 15, 2011 11:42 am
Re: TSL2561 and Raspberry Pi
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:
That's the same operation as the pseudocode 16-bit read.
Note that there are both signed and unsigned versions of the read functions.
Code: Select all
hibyte = self.bus.read_byte_data(self.address, reg)
result = (hibyte << 8) + self.bus.read_byte_data(self.address, reg+1)
Note that there are both signed and unsigned versions of the read functions.
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.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.
-
- Posts: 25
- Joined: Sun Dec 02, 2012 5:15 pm
Re: TSL2561 and Raspberry Pi
I'm pretty confused then... Can you take a look at my code?
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!
Code: Select all
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()
Thanks so much for your help!
- adafruit_support_rick
- Posts: 35092
- Joined: Tue Mar 15, 2011 11:42 am
Re: TSL2561 and Raspberry Pi
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();"):
So, to enable, our register selection will be (TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL). These are constants defined in TSL2561.h:
and the value to write is
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:
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:
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.
Code: Select all
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);
}
Code: Select all
#define TSL2561_COMMAND_BIT (0x80)
. . .
TSL2561_REGISTER_CONTROL = 0x00,
. . .
Code: Select all
#define TSL2561_CONTROL_POWERON (0x03)
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
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);
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
uint32_t x;
x = read16(0xAE);
x <<= 16;
x |= read16(0xAC);
- static
- Posts: 188
- Joined: Thu Dec 23, 2010 6:21 pm
Re: TSL2561 and Raspberry Pi
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
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
-
- Posts: 25
- Joined: Sun Dec 02, 2012 5:15 pm
Re: TSL2561 and Raspberry Pi
@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...
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...
- static
- Posts: 188
- Joined: Thu Dec 23, 2010 6:21 pm
Re: TSL2561 and Raspberry Pi
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?
Also, the data sheet mentions a 400msec delay when the chip is starting up. Could that be the problem?
Please be positive and constructive with your questions and comments.