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");
65 if (!this->
read_byte(TSL2591_COMMAND_BIT | TSL2591_REGISTER_DEVICE_ID, &
id)) {
66 ESP_LOGE(TAG,
"I2C read failed");
72 ESP_LOGE(TAG,
"Unknown chip ID");
82 ESP_LOGCONFIG(TAG,
"TSL2591:");
86 ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
90 ESP_LOGCONFIG(TAG,
" Name: %s", this->
name_);
93 std::string gain_word =
"unknown";
101 gain_word =
"medium";
109 gain_word =
"maximum";
117 int timing_ms = (1 + raw_timing) * 100;
120 " Integration Time: %d ms\n"
121 " Power save mode enabled: %s\n"
122 " Device factor: %f\n"
123 " Glass attenuation factor: %f",
132 LOG_UPDATE_INTERVAL(
this);
142 ESP_LOGD(TAG,
"Got illuminance: combined 0x%" PRIX32
", full %d, IR %d, vis %d. Calc lux: %f. Actual gain: %d.",
143 combined, full, infrared, visible, lux, actual_gain);
167#define interval_name "tsl2591_interval_for_update"
172 ESP_LOGD(TAG,
"Elapsed %3llu ms; still waiting for valid ADC", (now - this->
interval_start_));
174 ESP_LOGW(TAG,
"Interval timeout for '%s' expired before ADCs became valid", this->
name_);
233 if (!this->
write_byte(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CONTROL,
235 ESP_LOGE(TAG,
"I2C write failed");
254 if (!this->
read_byte(TSL2591_COMMAND_BIT | TSL2591_REGISTER_STATUS, &
status)) {
255 ESP_LOGE(TAG,
"I2C read failed");
268 const uint8_t mini_delay = 100;
269 for (uint16_t d = 0; d < 620; d += mini_delay) {
275 ESP_LOGD(TAG,
" after %3d ms: ADC valid? %s", d, avalid ?
"true" :
"false");
281 ESP_LOGE(TAG,
"Device '%s' returned invalid readings", this->
name_);
291 uint8_t ch0low, ch0high, ch1low, ch1high;
294 if (!this->
read_byte(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CHAN0_LOW, &ch0low)) {
295 ESP_LOGE(TAG,
"I2C read failed");
298 if (!this->
read_byte(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CHAN0_HIGH, &ch0high)) {
299 ESP_LOGE(TAG,
"I2C read failed");
302 ch0_16 = (ch0high << 8) | ch0low;
303 if (!this->
read_byte(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CHAN1_LOW, &ch1low)) {
304 ESP_LOGE(TAG,
"I2C read failed");
307 if (!this->
read_byte(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CHAN1_HIGH, &ch1high)) {
308 ESP_LOGE(TAG,
"I2C read failed");
311 ch1_16 = (ch1high << 8) | ch1low;
312 x32 = (ch1_16 << 16) | ch0_16;
326 return (combined_illuminance & 0xFFFF);
329 return (combined_illuminance >> 16);
332 return ((combined_illuminance & 0xFFFF) - (combined_illuminance >> 16));
335 ESP_LOGE(TAG,
"get_illuminance() caller requested an unknown channel: %d", channel);
356 if ((full_spectrum == max_count) || (infrared == max_count)) {
358 ESP_LOGW(TAG,
"Apparent saturation on '%s'; try reducing the gain or integration time", this->
name_);
362 if ((full_spectrum == 0) && (infrared == 0)) {
364 ESP_LOGW(TAG,
"Zero reading on both '%s' sensors", this->
name_);
371 switch (this->
gain_) {
400 float lux = (((float) full_spectrum - (float) infrared)) * (1.0F - ((
float) infrared / (
float) full_spectrum)) / cpl;
401 return std::max(lux, 0.0F);
421 switch (this->
gain_) {
423 if (full_spectrum < 54) {
425 }
else if (full_spectrum < 875) {
430 if (full_spectrum < 57) {
432 }
else if (full_spectrum < 1365) {
434 }
else if (full_spectrum > 62000 / fs_divider) {
439 if (full_spectrum < 920) {
441 }
else if (full_spectrum > 62000 / fs_divider) {
446 if (full_spectrum > 62000 / fs_divider)
451 if (this->
gain_ != new_gain) {
452 this->
gain_ = new_gain;
455 ESP_LOGD(TAG,
"Gain setting: %d", this->
gain_);
463 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()
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.