8static const char *
const TAG =
"tsl2591.sensor";
11#define TSL2591_COMMAND_BIT (0xA0)
12#define TSL2591_ENABLE_POWERON (0x01)
13#define TSL2591_ENABLE_POWEROFF (0x00)
14#define TSL2591_ENABLE_AEN (0x02)
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,
"I2C write failed");
34 if (!this->
write_byte(TSL2591_COMMAND_BIT | TSL2591_REGISTER_ENABLE, TSL2591_ENABLE_POWEROFF)) {
35 ESP_LOGE(TAG,
"I2C write failed");
46 ESP_LOGCONFIG(TAG,
"Running setup for address 0x%02X", this->
address_);
66 if (!this->
read_byte(TSL2591_COMMAND_BIT | TSL2591_REGISTER_DEVICE_ID, &
id)) {
67 ESP_LOGE(TAG,
"I2C read failed");
73 ESP_LOGE(TAG,
"Unknown chip ID");
83 ESP_LOGCONFIG(TAG,
"TSL2591:");
87 ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
91 ESP_LOGCONFIG(TAG,
" Name: %s", this->
name_);
94 std::string gain_word =
"unknown";
102 gain_word =
"medium";
110 gain_word =
"maximum";
118 int timing_ms = (1 + raw_timing) * 100;
121 " Integration Time: %d ms\n"
122 " Power save mode enabled: %s\n"
123 " Device factor: %f\n"
124 " Glass attenuation factor: %f",
133 LOG_UPDATE_INTERVAL(
this);
143 ESP_LOGD(TAG,
"Got illuminance: combined 0x%" PRIX32
", full %d, IR %d, vis %d. Calc lux: %f. Actual gain: %d.",
144 combined, full, infrared, visible, lux, actual_gain);
168#define interval_name "tsl2591_interval_for_update"
173 ESP_LOGD(TAG,
"Elapsed %3llu ms; still waiting for valid ADC", (now - this->
interval_start_));
175 ESP_LOGW(TAG,
"Interval timeout for '%s' expired before ADCs became valid", this->
name_);
234 if (!this->
write_byte(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CONTROL,
236 ESP_LOGE(TAG,
"I2C write failed");
255 if (!this->
read_byte(TSL2591_COMMAND_BIT | TSL2591_REGISTER_STATUS, &
status)) {
256 ESP_LOGE(TAG,
"I2C read failed");
269 const uint8_t mini_delay = 100;
270 for (uint16_t d = 0; d < 620; d += mini_delay) {
276 ESP_LOGD(TAG,
" after %3d ms: ADC valid? %s", d, avalid ?
"true" :
"false");
282 ESP_LOGE(TAG,
"Device '%s' returned invalid readings", this->
name_);
292 uint8_t ch0low, ch0high, ch1low, ch1high;
295 if (!this->
read_byte(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CHAN0_LOW, &ch0low)) {
296 ESP_LOGE(TAG,
"I2C read failed");
299 if (!this->
read_byte(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CHAN0_HIGH, &ch0high)) {
300 ESP_LOGE(TAG,
"I2C read failed");
303 ch0_16 = (ch0high << 8) | ch0low;
304 if (!this->
read_byte(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CHAN1_LOW, &ch1low)) {
305 ESP_LOGE(TAG,
"I2C read failed");
308 if (!this->
read_byte(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CHAN1_HIGH, &ch1high)) {
309 ESP_LOGE(TAG,
"I2C read failed");
312 ch1_16 = (ch1high << 8) | ch1low;
313 x32 = (ch1_16 << 16) | ch0_16;
327 return (combined_illuminance & 0xFFFF);
330 return (combined_illuminance >> 16);
333 return ((combined_illuminance & 0xFFFF) - (combined_illuminance >> 16));
336 ESP_LOGE(TAG,
"get_illuminance() caller requested an unknown channel: %d", channel);
357 if ((full_spectrum == max_count) || (infrared == max_count)) {
359 ESP_LOGW(TAG,
"Apparent saturation on '%s'; try reducing the gain or integration time", this->
name_);
363 if ((full_spectrum == 0) && (infrared == 0)) {
365 ESP_LOGW(TAG,
"Zero reading on both '%s' sensors", this->
name_);
372 switch (this->
gain_) {
401 float lux = (((float) full_spectrum - (float) infrared)) * (1.0F - ((
float) infrared / (
float) full_spectrum)) / cpl;
402 return std::max(lux, 0.0F);
422 switch (this->
gain_) {
424 if (full_spectrum < 54) {
426 }
else if (full_spectrum < 875) {
431 if (full_spectrum < 57) {
433 }
else if (full_spectrum < 1365) {
435 }
else if (full_spectrum > 62000 / fs_divider) {
440 if (full_spectrum < 920) {
442 }
else if (full_spectrum > 62000 / fs_divider) {
447 if (full_spectrum > 62000 / fs_divider)
452 if (this->
gain_ != new_gain) {
453 this->
gain_ = new_gain;
456 ESP_LOGD(TAG,
"Gain setting: %d", this->
gain_);
464 switch (this->
gain_) {
virtual void mark_failed()
Mark this component as failed.
void set_interval(const std::string &name, uint32_t interval, std::function< void()> &&f)
Set an interval function with a unique name.
bool cancel_interval(const std::string &name)
Cancel an interval function.
void status_clear_warning()
uint8_t address_
store the address of the device on the bus
bool write_byte(uint8_t a_register, uint8_t data, bool stop=true)
bool read_byte(uint8_t a_register, uint8_t *data, bool stop=true)
Base-class for all sensors.
void publish_state(float state)
Publish a new state to the front-end.
uint64_t interval_timeout_
TSL2591IntegrationTime integration_time_
void dump_config() override
Used by ESPHome framework.
float get_setup_priority() const override
Used by ESPHome framework.
TSL2591ComponentGain component_gain_
void automatic_gain_update(uint16_t full_spectrum)
Updates the gain setting based on the most recent full spectrum reading.
bool is_adc_valid()
Are the device ADC values valid?
sensor::Sensor * infrared_sensor_
float get_calculated_lux(uint16_t full_spectrum, uint16_t infrared)
Calculates and returns a lux value based on the ADC readings.
sensor::Sensor * calculated_lux_sensor_
void set_visible_sensor(sensor::Sensor *visible_sensor)
Used by ESPHome framework.
void set_device_and_glass_attenuation_factors(float device_factor, float glass_attenuation_factor)
Sets the device and glass attenuation factors.
sensor::Sensor * full_spectrum_sensor_
void set_integration_time(TSL2591IntegrationTime integration_time)
Used by ESPHome framework.
void set_calculated_lux_sensor(sensor::Sensor *calculated_lux_sensor)
Used by ESPHome framework.
uint32_t get_combined_illuminance()
Get the combined illuminance value.
void set_name(const char *name)
Sets the name for this instance of the device.
void interval_function_for_update_()
void disable_if_power_saving_()
float glass_attenuation_factor_
sensor::Sensor * visible_sensor_
void set_infrared_sensor(sensor::Sensor *infrared_sensor)
Used by ESPHome framework.
sensor::Sensor * actual_gain_sensor_
void set_actual_gain_sensor(sensor::Sensor *actual_gain_sensor)
Used by ESPHome framework.
void set_gain(TSL2591ComponentGain gain)
Used by ESPHome framework.
void enable()
Powers on the TSL2591 device and enables its sensors.
void update() override
Used by ESPHome framework.
void set_integration_time_and_gain(TSL2591IntegrationTime integration_time, TSL2591Gain gain)
Set device integration time and gain.
void set_full_spectrum_sensor(sensor::Sensor *full_spectrum_sensor)
Used by ESPHome framework.
void disable()
Powers off the TSL2591 device.
float get_actual_gain()
Reads the actual gain used.
uint16_t get_illuminance(TSL2591SensorChannel channel)
Get an individual sensor channel reading.
bool power_save_mode_enabled_
void setup() override
Used by ESPHome framework.
void set_power_save_mode(bool enable)
Should the device be powered down between readings?
IntegrationTime501 integration_time
const float DATA
For components that import data from directly connected sensors like DHT.
TSL2591Gain
Enum listing all gain settings for the TSL2591.
TSL2591ComponentGain
Enum listing all gain settings for the TSL2591 component.
TSL2591IntegrationTime
Enum listing all conversion/integration time settings for the TSL2591.
@ TSL2591_INTEGRATION_TIME_100MS
TSL2591SensorChannel
Enum listing sensor channels.
@ TSL2591_SENSOR_CHANNEL_INFRARED
@ TSL2591_SENSOR_CHANNEL_VISIBLE
@ TSL2591_SENSOR_CHANNEL_FULL_SPECTRUM
Providing packet encoding functions for exchanging data with a remote host.
void IRAM_ATTR HOT delay(uint32_t ms)
uint32_t IRAM_ATTR HOT millis()
T id(T value)
Helper function to make id(var) known from lambdas work in custom components.