9static constexpr uint32_t ADC_WAIT_INTERVAL_ID = 0;
12#define TSL2591_COMMAND_BIT (0xA0)
13#define TSL2591_ENABLE_POWERON (0x01)
14#define TSL2591_ENABLE_POWEROFF (0x00)
15#define TSL2591_ENABLE_AEN (0x02)
18#define TSL2591_REGISTER_ENABLE (0x00)
19#define TSL2591_REGISTER_CONTROL (0x01)
20#define TSL2591_REGISTER_DEVICE_ID (0x12)
21#define TSL2591_REGISTER_STATUS (0x13)
22#define TSL2591_REGISTER_CHAN0_LOW (0x14)
23#define TSL2591_REGISTER_CHAN0_HIGH (0x15)
24#define TSL2591_REGISTER_CHAN1_LOW (0x16)
25#define TSL2591_REGISTER_CHAN1_HIGH (0x17)
29 if (!this->
write_byte(TSL2591_COMMAND_BIT | TSL2591_REGISTER_ENABLE, TSL2591_ENABLE_POWERON | TSL2591_ENABLE_AEN)) {
30 ESP_LOGE(TAG,
"I2C write failed");
35 if (!this->
write_byte(TSL2591_COMMAND_BIT | TSL2591_REGISTER_ENABLE, TSL2591_ENABLE_POWEROFF)) {
36 ESP_LOGE(TAG,
"I2C write failed");
65 if (!this->
check_chip_id(
this, TSL2591_COMMAND_BIT | TSL2591_REGISTER_DEVICE_ID, 0x50))
73 ESP_LOGCONFIG(TAG,
"TSL2591:");
79 ESP_LOGCONFIG(TAG,
" Name: %s", this->
name_);
82 std::string gain_word =
"unknown";
98 gain_word =
"maximum";
106 int timing_ms = (1 + raw_timing) * 100;
109 " Integration Time: %d ms\n"
110 " Power save mode enabled: %s\n"
111 " Device factor: %f\n"
112 " Glass attenuation factor: %f",
121 LOG_UPDATE_INTERVAL(
this);
131 ESP_LOGD(TAG,
"Got illuminance: combined 0x%" PRIX32
", full %d, IR %d, vis %d. Calc lux: %f. Actual gain: %d.",
132 combined, full, infrared, visible, lux, actual_gain);
159 ESP_LOGD(TAG,
"Elapsed %3llu ms; still waiting for valid ADC", (now - this->
interval_start_));
161 ESP_LOGW(TAG,
"Interval timeout for '%s' expired before ADCs became valid", this->
name_);
216 if (!this->
write_byte(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CONTROL,
218 ESP_LOGE(TAG,
"I2C write failed");
231 if (!this->
read_byte(TSL2591_COMMAND_BIT | TSL2591_REGISTER_STATUS, &
status)) {
232 ESP_LOGE(TAG,
"I2C read failed");
245 const uint8_t mini_delay = 100;
246 for (uint16_t d = 0; d < 620; d += mini_delay) {
252 ESP_LOGD(TAG,
" after %3d ms: ADC valid? %s", d, avalid ? LOG_STR_LITERAL(
"true") : LOG_STR_LITERAL(
"false"));
258 ESP_LOGE(TAG,
"Device '%s' returned invalid readings", this->
name_);
268 uint8_t ch0low, ch0high, ch1low, ch1high;
271 if (!this->
read_byte(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CHAN0_LOW, &ch0low)) {
272 ESP_LOGE(TAG,
"I2C read failed");
275 if (!this->
read_byte(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CHAN0_HIGH, &ch0high)) {
276 ESP_LOGE(TAG,
"I2C read failed");
279 ch0_16 = (ch0high << 8) | ch0low;
280 if (!this->
read_byte(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CHAN1_LOW, &ch1low)) {
281 ESP_LOGE(TAG,
"I2C read failed");
284 if (!this->
read_byte(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CHAN1_HIGH, &ch1high)) {
285 ESP_LOGE(TAG,
"I2C read failed");
288 ch1_16 = (ch1high << 8) | ch1low;
289 x32 = (ch1_16 << 16) | ch0_16;
303 return (combined_illuminance & 0xFFFF);
306 return (combined_illuminance >> 16);
309 uint16_t full = combined_illuminance & 0xFFFF;
310 uint16_t ir = combined_illuminance >> 16;
311 return (ir > full) ? 0 : (full - ir);
314 ESP_LOGE(TAG,
"get_illuminance() caller requested an unknown channel: %d", channel);
335 if ((full_spectrum == max_count) || (infrared == max_count)) {
337 ESP_LOGW(TAG,
"Apparent saturation on '%s'; try reducing the gain or integration time", this->
name_);
341 if ((full_spectrum == 0) && (infrared == 0)) {
343 ESP_LOGW(TAG,
"Zero reading on both '%s' sensors", this->
name_);
350 switch (this->
gain_) {
379 float lux = (((float) full_spectrum - (float) infrared)) * (1.0F - ((
float) infrared / (
float) full_spectrum)) / cpl;
380 return std::max(lux, 0.0F);
400 switch (this->
gain_) {
402 if (full_spectrum < 54) {
404 }
else if (full_spectrum < 875) {
409 if (full_spectrum < 57) {
411 }
else if (full_spectrum < 1365) {
413 }
else if (full_spectrum > 62000 / fs_divider) {
418 if (full_spectrum < 920) {
420 }
else if (full_spectrum > 62000 / fs_divider) {
425 if (full_spectrum > 62000 / fs_divider)
430 if (this->
gain_ != new_gain) {
431 this->
gain_ = new_gain;
434 ESP_LOGD(TAG,
"Gain setting: %d", this->
gain_);
442 switch (this->
gain_) {
bool cancel_interval(const char *name)
Cancel an interval function.
void set_interval(const char *name, uint32_t interval, std::function< void()> &&f)
Set an interval function with a const char* name.
void status_clear_warning()
bool check_chip_id(Component *component, uint8_t a_register, uint8_t expected, uint8_t mask=0xFF)
Read the 8-bit ID at a_register and accept it when it matches expected in the bits set in mask.
bool write_byte(uint8_t a_register, uint8_t data) const
bool read_byte(uint8_t a_register, uint8_t *data)
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.
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_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 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 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.
IntegrationTime501 integration_time
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
ESPHOME_LOG_TAG(TAG, "tsl2591.sensor")
void HOT delay(uint32_t ms)
uint32_t IRAM_ATTR HOT millis()