8 static const char *
const TAG =
"tsl2591.sensor";
11 #define TSL2591_COMMAND_BIT (0xA0) // 1010 0000: bits 7 and 5 for 'command, normal' 12 #define TSL2591_ENABLE_POWERON (0x01) // Flag for ENABLE register, to enable 13 #define TSL2591_ENABLE_POWEROFF (0x00) // Flag for ENABLE register, to disable 14 #define TSL2591_ENABLE_AEN (0x02) // Flag for ENABLE register, to turn on ADCs 17 #define TSL2591_REGISTER_ENABLE (0x00) 18 #define TSL2591_REGISTER_CONTROL (0x01) 19 #define TSL2591_REGISTER_DEVICE_ID (0x12) 20 #define TSL2591_REGISTER_STATUS (0x13) 21 #define TSL2591_REGISTER_CHAN0_LOW (0x14) 22 #define TSL2591_REGISTER_CHAN0_HIGH (0x15) 23 #define TSL2591_REGISTER_CHAN1_LOW (0x16) 24 #define TSL2591_REGISTER_CHAN1_HIGH (0x17) 28 if (!this->
write_byte(TSL2591_COMMAND_BIT | TSL2591_REGISTER_ENABLE, TSL2591_ENABLE_POWERON | TSL2591_ENABLE_AEN)) {
29 ESP_LOGE(TAG,
"Failed I2C write during enable()");
34 if (!this->
write_byte(TSL2591_COMMAND_BIT | TSL2591_REGISTER_ENABLE, TSL2591_ENABLE_POWEROFF)) {
35 ESP_LOGE(TAG,
"Failed I2C write during disable()");
65 ESP_LOGI(TAG,
"Setting up TSL2591 sensor at I2C address 0x%02X", address);
68 if (!this->
read_byte(TSL2591_COMMAND_BIT | TSL2591_REGISTER_DEVICE_ID, &
id)) {
69 ESP_LOGE(TAG,
"Failed I2C read during setup()");
76 "Could not find the TSL2591 sensor. The ID register of the device at address 0x%02X reported 0x%02X " 88 ESP_LOGCONFIG(TAG,
"TSL2591:");
92 ESP_LOGE(TAG,
"Communication with TSL2591 failed earlier, during setup");
96 ESP_LOGCONFIG(TAG,
" Name: %s", this->
name_);
99 std::string gain_word =
"unknown";
107 gain_word =
"medium";
115 gain_word =
"maximum";
122 ESP_LOGCONFIG(TAG,
" Gain: %dx (%s)", gain, gain_word.c_str());
124 int timing_ms = (1 + raw_timing) * 100;
125 ESP_LOGCONFIG(TAG,
" Integration Time: %d ms", timing_ms);
134 LOG_UPDATE_INTERVAL(
this);
143 ESP_LOGD(TAG,
"Got illuminance: combined 0x%X, full %d, IR %d, vis %d. Calc lux: %f", combined, full, infrared,
163 #define interval_name "tsl2591_interval_for_update" 168 ESP_LOGD(TAG,
"Elapsed %3llu ms; still waiting for valid ADC", (now - this->
interval_start_));
170 ESP_LOGW(TAG,
"Interval timeout for TSL2591 '%s' expired before ADCs became valid.", this->
name_);
225 if (!this->
write_byte(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CONTROL,
227 ESP_LOGE(TAG,
"Failed I2C write during set_integration_time_and_gain()");
246 if (!this->
read_byte(TSL2591_COMMAND_BIT | TSL2591_REGISTER_STATUS, &status)) {
247 ESP_LOGE(TAG,
"Failed I2C read during is_adc_valid()");
250 return status & 0x01;
260 const uint8_t mini_delay = 100;
261 for (uint16_t d = 0; d < 620; d += mini_delay) {
267 ESP_LOGD(TAG,
" after %3d ms: ADC valid? %s", d, avalid ?
"true" :
"false");
273 ESP_LOGE(TAG,
"tsl2591 device '%s' did not return valid readings.", this->
name_);
283 uint8_t ch0low, ch0high, ch1low, ch1high;
286 if (!this->
read_byte(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CHAN0_LOW, &ch0low)) {
287 ESP_LOGE(TAG,
"Failed I2C read during get_combined_illuminance()");
290 if (!this->
read_byte(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CHAN0_HIGH, &ch0high)) {
291 ESP_LOGE(TAG,
"Failed I2C read during get_combined_illuminance()");
294 ch0_16 = (ch0high << 8) | ch0low;
295 if (!this->
read_byte(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CHAN1_LOW, &ch1low)) {
296 ESP_LOGE(TAG,
"Failed I2C read during get_combined_illuminance()");
299 if (!this->
read_byte(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CHAN1_HIGH, &ch1high)) {
300 ESP_LOGE(TAG,
"Failed I2C read during get_combined_illuminance()");
303 ch1_16 = (ch1high << 8) | ch1low;
304 x32 = (ch1_16 << 16) | ch0_16;
318 return (combined_illuminance & 0xFFFF);
321 return (combined_illuminance >> 16);
324 return ((combined_illuminance & 0xFFFF) - (combined_illuminance >> 16));
327 ESP_LOGE(TAG,
"TSL2591Component::get_illuminance() caller requested an unknown channel: %d", channel);
348 if ((full_spectrum == max_count) || (infrared == max_count)) {
350 ESP_LOGW(TAG,
"Apparent saturation on TSL2591 (%s). You could reduce the gain.", this->
name_);
354 if ((full_spectrum == 0) && (infrared == 0)) {
356 ESP_LOGW(TAG,
"Zero reading on both TSL2591 (%s) sensors. Is the device having a problem?", this->
name_);
363 switch (this->
gain_) {
393 float lux = (((float) full_spectrum - (
float) infrared)) * (1.0F - ((float) infrared / (
float) full_spectrum)) / cpl;
394 return std::max(lux, 0.0F);
414 switch (this->
gain_) {
416 if (full_spectrum < 54) {
418 }
else if (full_spectrum < 875) {
423 if (full_spectrum < 57) {
425 }
else if (full_spectrum < 1365) {
427 }
else if (full_spectrum > 62000 / fs_divider) {
432 if (full_spectrum < 920) {
434 }
else if (full_spectrum > 62000 / fs_divider) {
439 if (full_spectrum > 62000 / fs_divider)
444 if (this->
gain_ != new_gain) {
445 this->
gain_ = new_gain;
448 ESP_LOGD(TAG,
"Gain setting: %d", this->
gain_);
void dump_config() override
Used by ESPHome framework.
bool read_byte(uint8_t a_register, uint8_t *data, bool stop=true)
sensor::Sensor * visible_sensor_
const float DATA
For components that import data from directly connected sensors like DHT.
void set_interval(const std::string &name, uint32_t interval, std::function< void()> &&f)
Set an interval function with a unique name.
bool power_save_mode_enabled_
void set_full_spectrum_sensor(sensor::Sensor *full_spectrum_sensor)
Used by ESPHome framework.
sensor::Sensor * calculated_lux_sensor_
uint64_t interval_timeout_
uint16_t get_illuminance(TSL2591SensorChannel channel)
Get an individual sensor channel reading.
void disable_if_power_saving_()
bool cancel_interval(const std::string &name)
Cancel an interval function.
void set_name(const char *name)
Sets the name for this instance of the device.
T id(T value)
Helper function to make id(var) known from lambdas work in custom components.
void set_calculated_lux_sensor(sensor::Sensor *calculated_lux_sensor)
Used by ESPHome framework.
TSL2591IntegrationTime
Enum listing all conversion/integration time settings for the TSL2591.
uint32_t IRAM_ATTR HOT millis()
sensor::Sensor * infrared_sensor_
void update() override
Used by ESPHome framework.
TSL2591ComponentGain component_gain_
void set_power_save_mode(bool enable)
Should the device be powered down between readings?
void set_integration_time_and_gain(TSL2591IntegrationTime integration_time, TSL2591Gain gain)
Set device integration time and gain.
void set_integration_time(TSL2591IntegrationTime integration_time)
Used by ESPHome framework.
void status_clear_warning()
void publish_state(float state)
Publish a new state to the front-end.
void setup() override
Used by ESPHome framework.
void set_infrared_sensor(sensor::Sensor *infrared_sensor)
Used by ESPHome framework.
sensor::Sensor * full_spectrum_sensor_
TSL2591ComponentGain
Enum listing all gain settings for the TSL2591 component.
void enable()
Powers on the TSL2591 device and enables its sensors.
TSL2591Gain
Enum listing all gain settings for the TSL2591.
TSL2591IntegrationTime integration_time_
TSL2591SensorChannel
Enum listing sensor channels.
bool write_byte(uint8_t a_register, uint8_t data, bool stop=true)
virtual void mark_failed()
Mark this component as failed.
void set_gain(TSL2591ComponentGain gain)
Used by ESPHome framework.
float glass_attenuation_factor_
void disable()
Powers off the TSL2591 device.
bool is_adc_valid()
Are the device ADC values valid?
float get_setup_priority() const override
Used by ESPHome framework.
Base-class for all sensors.
void automatic_gain_update(uint16_t full_spectrum)
Updates the gain setting based on the most recent full spectrum reading.
void set_visible_sensor(sensor::Sensor *visible_sensor)
Used by ESPHome framework.
void interval_function_for_update_()
void set_device_and_glass_attenuation_factors(float device_factor, float glass_attenuation_factor)
Sets the device and glass attenuation factors.
void IRAM_ATTR HOT delay(uint32_t ms)
float get_calculated_lux(uint16_t full_spectrum, uint16_t infrared)
Calculates and returns a lux value based on the ADC readings.
uint32_t get_combined_illuminance()
Get the combined illuminance value.