To interface the TSL2591 high-precision light sensor with an STM32 microcontroller, you can use the I2C interface provided by the sensor. Here's a detailed guide covering hardware setup, initialization, reading data, and calculating lux values.
1. Overview
- TSL2591: Digital light sensor with high dynamic range (~188µLux to 88,000 Lux).
- Interface: I2C
- Key registers: COMMAND, ENABLE, CONTROL, and data registers for channels.
2. Hardware Connection
Pull-up resistors (~4.7kΩ) recommended on SDA/SCL lines.
3. I2C Initialization (STM32CubeMX)
- Enable I2C1 (or any available)
- Configure SDA/SCL pins
- Generate code using HAL drivers
4. I2C Address and Registers
I2C Address: 0x29 << 1 = 0x52 (for HAL)
Command Bit: OR 0xA0 to register address when reading/writing
Key Registers:
- 0x00: ENABLE
- 0x01: CONTROL
- 0x14~0x19: ADC data registers (2 channels, 16-bit each)
5. Basic Initialization Sequence
a) Enable Sensor
c
// Enable ALS (Ambient Light Sensing)
HAL_I2C_Mem_Write(&hi2c1, 0x52, 0xA0 | 0x00, 1, (uint8_t[]){0x03}, 1, HAL_MAX_DELAY); // Power ON + ALS Enable
b) Set Integration Time and Gain
c
// Set CONTROL register: Gain = Medium, Integration = 100ms
// Gain = 01 (Medium), Integration = 100ms (0x01)
// CONTROL = 0x10 | 0x01 = 0x11
HAL_I2C_Mem_Write(&hi2c1, 0x52, 0xA0 | 0x01, 1, (uint8_t[]){0x11}, 1, HAL_MAX_DELAY);
6. Reading Data
c
uint8_t buffer[2];
uint16_t ch0, ch1;
// Read CH0 (Full Spectrum)
HAL_I2C_Mem_Read(&hi2c1, 0x52, 0xA0 | 0x14, 1, buffer, 2, HAL_MAX_DELAY);
ch0 = buffer[0] | (buffer[1] << 8);
// Read CH1 (Infrared)
HAL_I2C_Mem_Read(&hi2c1, 0x52, 0xA0 | 0x16, 1, buffer, 2, HAL_MAX_DELAY);
ch1 = buffer[0] | (buffer[1] << 8);
7. Lux Calculation (Simplified)
Use Adafruit’s algorithm for TSL2591:
c
float lux;
if (ch0 == 0xFFFF || ch1 == 0xFFFF) {
lux = -1; // sensor saturated
} else {
float atime = 100.0f; // integration time in ms
float again = 25.0f; // medium gain
float cpl = (atime * again) / 408.0f;
lux = ((float)ch0 - (float)ch1) * (1.0f - ((float)ch1 / (float)ch0)) / cpl;
}
This is a simplified version. For accurate lux calculation, consider full spectral response compensation.
8. Best Practices
- Wait after enabling sensor (integration time + margin) before reading data.
- Check for saturation (0xFFFF).
- Use HAL_Delay() or non-blocking timing to ensure measurement is ready.
- Power down sensor when idle to save energy.
Optional: Create Driver
You can encapsulate the initialization and reading functions in a TSL2591 driver (tsl2591.h/.c).
Top comments (0)