Light Sensor
| ||
Introduction
Light Sensor, detects the ambient light intensity, I2C interface
More |
Specification
- Operating voltage: 3.3V ~ 5V
- Effective range: 0-10000Lux
- Output form: digital
- Communication method: I2C
- Size: 25.04mm × 15.47mm
- Fixing hole size: 2.0mm
Application
- Applications include street light control, security lighting, sunlight harvesting, machine vision, and power instrument clusters, and are ideal for tablets, mobile phones, and digital cameras.
Interface
Pin Number | Identification | Pin Description |
1 | VCC | Power Positive (2.7V-5V) |
2 | GND | Power Ground |
3 | SDA | I2C data line |
4 | SCL | I2C clock line |
5 | INT | Digital interrupt output |
Getting Started
Schematic Diagram
Timing analysis
TSL2581 has a data line and a clock signal line and adopts the I2C communication mode. There are three types of signals that will be used in the course of the I2C bus data transmission. They are the Start signal, Stop signal, and Ack signal.
- Start signal: When SCL is HIGH and SDA jumps from HIGH to LOW, the data transmission starts.
- Stop signal: When SCL is HIGH and SDA jumps from LOW to HIGH, the data transmission stops.
- Ack signal: When the receiver IC has received 8 bits of data, it will send out a special LOW-level pulse to the transmitter IC to indicate that the data have been received.
I2C writing
In the beginning, the Host (here is STM32, and we will call it the Host hereafter) sends out a start signal, and combines the 7 bit of I2C slave address with the Write bit, then, sends this 8-bit of data to the Slave (here is TSL2581 sensor, and we will refer it to the Slave hereafter). Then, the Slave sends back an ACK signal when it has received the data. The Host transmits the slave address of the command register to the Slave as soon as it received the ACK signal. And the Slave responds to an ACK signal when it has received the slave's address. By following, the Host sends the value of the command registers to the Slave. And the Slave responds with an ACK signal once again. The I2C writing operation will be continued till the Host sends out a stop signal.
I2C reading
In the beginning, the Host sends out a start signal, and combines the 7 bits of I2C slave address with the Write bit, then, sends this 8 bit of data to the Slave. Then, the Slave sends back an ACK signal when it has received the data. The Host transmits the slave address of the command register to the Slave as soon as it received the ACK signal. And the Slave responds to an ACK signal when it has received the slave's address. At this moment, the Host sends out a start signal once again, and combines its 7-bit slave address with the Read bit, then, sends this 8-bit of data to the Slave. And then, the Slave responds to an ACK signal to the Host when it has received the data and sends out the value stored in the Slave register to the Host. The Host sends back an ACK signal as soon as it received the value. The I2C communication will be continued, till the Host sends out a stop signal.
Command Code
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
CMD | TRANSACTION | ADDRESS |
- CMD: select the command register. This bit should be set to 1 for addressing the COMMAND register.
- TRANSACTION: These bits can select the R/W mode and the special function register. For 10, select the I2C reading mode which supports the read block protocol. For 00, select the I2C writing mode. For 11, select the special function register. Under this model, the ADDRESS can be set as follows:
- 0 0001: clear the interrupt; since the interrupt output would remain at 0 after the sensor triggered the interrupt, you should set this bit to 1 by hand to clear the interrupt;
- 0 0010: stop the manual integration;
- 0 0011: start the manual integration.
- ADDRESS: As the description above, you can know that when bit 5 and bit 6 are set to 10, the I2C reading mode is selected; when 00, the I2C writing mode is selected. Under the I2C R/W mode, the lower 5 bits are the addresses of the registers. In the following section, we will illustrate the address settings and configuration codes.
I2C address
This module has a digital (i2c) interface. And there are three kinds of addresses applicable, as the table lists below. You can select one of them. The sensor's internal address is a 7-bit address.
ADDR | Address |
VCC | 0X49 |
FLOAT | 0X39 |
GND | 0X29 |
Notes: The ADDR pin on the development board here is set to FLOAT by default.
Device ID
The device ID can be obtained by writing the registered address 0x12 as below:
ReadBuffer = I2C_DEV_Read(COMMAND_CMD |TRANSACTION |ID);
As the relative datasheet describes, the device ID is stored in the 8 bits register, of which the higher 4 bits store the part number of the device, while the lower 4 bits store the silicon version number of the device. However, the datasheet has not presented the silicon version number. So, we need to deal with the data read out as follows:
ID = ReadBuffer & 0XF0;
Now, we can get the device ID. TakingTSL2581 as an example, its device ID is 0x90.
Demo description (take STM32 for example)
According to the description of the datasheet, you should power up the device to make it run before performing a write operation and reading the value from two channels of ADC. So here is the configuration code to power up the device.
I2C_DEV_Write(ADDR_FLOAT_Write,COMMAND_CMD| CONTROL,ADC_EN|CONTROL_POWERON);
In which,
- ADDR_FLOAT_Write: the address of I2C, its lowest bit is a write data bit;
- COMMAND_CMD: On I2C command writing, its highest bit should be set to 1, so as to make sure the written data is valid;
- CONTROL: control register address: 00h, it is able to configure ADC enable and device enable;
- ADC_EN: enable the ADC channel to start integrating operation;
- CONTROL_POWERON: enable the device.
After powering up the device, you should configure the integration time to 400ms and the Gain of the channel to 16 times. Since TSL2581 can perform an integration every 2.7ms, there will be 148 integration periods with an integration time of 400ms.
- I2C_DEV_Write(ADDR_FLOAT_Write,COMMAND_CMD | TIMING, INTEGRATIONTIME_400MS);
- I2C_DEV_Write(ADDR_FLOAT_Write,COMMAND_CMD | ANALOG, GAIN_16X);
Note: The Gain parameter GAIN_16X is suitable for indoor test due to small measurement range; if you want to do some outdoor test, set the Gain to GAIN_1X to get the max measurement range.
Now, you can read the value of the channels. According to the definition of the datasheet, the lower bit of the data would be read out first. (Here we only present the configuration code of the channel 0. The channel 1 can be configured at the same way.)
- DataLow = I2C_DEV_Read(COMMAND_CMD | TRANSACTION | DATA0LOW);
- DataHigh = I2C_DEV_Read(COMMAND_CMD | TRANSACTION | DATA0HIGH);
- Channel_0 = 256 * DataHigh + DataLow ;
The lower bit of the data is read out first, and then the higher bit is followed. There will be two sets of 8 bit data. Combine them into a 16 bit data after reading out. What you can get from the channel 0 is the value of visible light and infrared light, and from the channel 1 is the value of infrared light, ch1 << ch2.
The values of the channels should be converted to the luminous intensity when you get them. In the configuration described above, we have set the integration time to 400ms, and the Gain to 16 times. To accurately get the current luminous intensity, we should scale the value. For the integration time is 400ms, the Maximum value of the channel is 65536.
chScale0 = 65536;
With the Gain of 16 times, this value would be reduced to 4096:
chScale0 = chScale0 >> 4; chScale1 = chScale0;
Here are the formulas for scaling:
channel0 = (Channel_0 * chScale0) >> 16; channel1 = (Channel_1 * chScale1) >> 16;
After scaling, calculate the ratio between channel 0 and channel 1 with the formula:
ratio1 = (channel1 << (RATIO_SCALE + 1)) / channel0;
in which,
- RATIO_SCALE = 9;
- ratio = (ratio1 + 1) >> 1;
Now, you can get the relationships listed below, according to the experience formulas:
if ((ratio >= 0X00) && (ratio <= K1C)) { b = B1C; m = M1C; } else if (ratio <= K2C) { b = B2C; m = M2C; } else if (ratio <= K3C) { b = B3C; m = M3C; } else if (ratio <= K4C) { b = B4C; m = M4C; } else if (ratio > K5C) { b = B5C; m = M5C; }
In which:
- When ratio <= 0.3, b = 0.130, m = 0.240
- When ratio <= 0.38, b = 0.1649, m = 0.3562
- When ratio <= 0.45, b = 0.0974, m = 0.1786
- When ratio <= 0.54, b = 0.062, m = 0.100
- When ratio > 0.54, b = m = 0
After calculated the multiple of the relative channel, you can export the current luminous intensity:
- temp = ((channel0 * b) - (channel1 * m));
- temp += (1 << (16 - 1));
- lux = temp >> 16;
Here, the Lux is the current luminous intensity.
Interrupt configuration
According to the datasheet, the interrupt threshold register is 03h-06h, in which 03h is the lower 8 bits of the lower threshold, 04h is the higher 8 bits of the lower threshold, 05h is the lower 8 bits of the higher threshold, and 06h is the higher 8bits of the higher threshold.
- DataLLow = min % 256;
- DataLHigh = min / 256;
- I2C_DEV_Write(ADDR_FLOAT_Write,COMMAND_CMD | THLLOW, DataLLow);
- I2C_DEV_Write(ADDR_FLOAT_Write,COMMAND_CMD | THLHIGH, DataLHigh);
The interrupt threshold register is only valid for channel 0, therefore the minimum threshold should not exceed 2^16.
When the value of channel 0 is lower than the given lower threshold or higher than the given higher threshold in a certain integration time, the interrupt output bit will be set to 1 and remain at this state till the special function register clears it by setting the TRANSACTION bit to 11. Also, the ADC will be disabled. To enable the ADC, you should configure the register CONTROL to power up the device.
I2C_DEV_Write(ADDR_FLOAT_Write,COMMAND_CMD | TRANSACTION_SPECIAL | SPECIAL_FUN_INTCLEAR, INTR_INTER_MODE); I2C_DEV_Write(ADDR_FLOAT_Write,COMMAND_CMD | CONTROL, ADC_EN | CONTROL_POWERON);
In which:
- TRANSACTION_SPECIAL = 0x60, it means TRANSACTION is set to 11;
- SPECIAL_FUN_INTCLEAR is ADDRESS, its value is 0 0001;
- INTR_INTER_MODE this parameter specifies the interrupt generated every 8 integration times. It allows channel 0 remain at a certain value for a while before the interrupt is triggered.
How to use
In the following section, we will present how to use the module with the XNUCLEO-F103RB (STM32F103R) and Arduino UNO development boards.
- Download the corresponding program to the development board;
- Connect the module to the development board and connect the board to your PC via a serial cable. Then, power up the development board, and start up the serial debugging software.
Here are the connections between the module and the development board.
Table 1. STM32 interface:
Port | XNUCLEO-F103RB |
VCC | 3V3/5V |
GND | GND |
SDA | PB9 |
SCL | PB8 |
INT | PA7 |
Table 2. Arduino UNO PLUS interface:
Port | Arduino |
VCC | 3.3V or 5V |
GND | GND |
SDA | SDA |
SCL | SCL |
INT | 13 |
Table 3. Serial port configuration:
Baud rate | 115200 |
Data bits | 8 |
Stop bit | 1 |
Parity bit | NONE |
Expected result: When the sensor gets close to different light sources, you can find that the serial data output changes as well. The data outputted on the screen is in the unit of LUX. For more detailed information on the testing, please refer to Appendix.
Appendix
The figure on the left shows the results of the luminous intensity measured by the sensor;
The figure on the right shows the testing result of the same light source measured by the TA8133 portable digital illuminometer.
Resources
FAQ
{{{5}}}
Support
Technical Support
If you need technical support or have any feedback/review, please click the Submit Now button to submit a ticket, Our support team will check and reply to you within 1 to 2 working days. Please be patient as we make every effort to help you to resolve the issue.
Working Time: 9 AM - 6 PM GMT+8 (Monday to Friday)