ESPHome 2025.9.0-dev
Loading...
Searching...
No Matches
tsl2561.cpp
Go to the documentation of this file.
1#include "tsl2561.h"
2#include "esphome/core/log.h"
3
4namespace esphome {
5namespace tsl2561 {
6
7static const char *const TAG = "tsl2561";
8
9static const uint8_t TSL2561_COMMAND_BIT = 0x80;
10static const uint8_t TSL2561_WORD_BIT = 0x20;
11static const uint8_t TSL2561_REGISTER_CONTROL = 0x00;
12static const uint8_t TSL2561_REGISTER_TIMING = 0x01;
13static const uint8_t TSL2561_REGISTER_ID = 0x0A;
14static const uint8_t TSL2561_REGISTER_DATA_0 = 0x0C;
15static const uint8_t TSL2561_REGISTER_DATA_1 = 0x0E;
16
18 uint8_t id;
19 if (!this->tsl2561_read_byte(TSL2561_REGISTER_ID, &id)) {
20 this->mark_failed();
21 return;
22 }
23
24 uint8_t timing;
25 if (!this->tsl2561_read_byte(TSL2561_REGISTER_TIMING, &timing)) {
26 this->mark_failed();
27 return;
28 }
29
30 timing &= ~0b00010000;
31 timing |= this->gain_ == TSL2561_GAIN_16X ? 0b00010000 : 0;
32
33 timing &= ~0b00000011;
34 timing |= this->integration_time_ & 0b11;
35
36 this->tsl2561_write_byte(TSL2561_REGISTER_TIMING, timing);
37}
39 LOG_SENSOR("", "TSL2561", this);
40 LOG_I2C_DEVICE(this);
41
42 if (this->is_failed()) {
43 ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
44 }
45
46 int gain = this->gain_ == TSL2561_GAIN_1X ? 1 : 16;
47 ESP_LOGCONFIG(TAG,
48 " Gain: %dx\n"
49 " Integration Time: %.1f ms",
51
52 LOG_UPDATE_INTERVAL(this);
53}
55 // Power on
56 if (!this->tsl2561_write_byte(TSL2561_REGISTER_CONTROL, 0b00000011)) {
57 this->status_set_warning();
58 return;
59 }
60
61 // Make sure the data is there when we will read it.
62 auto timeout = static_cast<uint32_t>(this->get_integration_time_ms_() + 20);
63
64 this->set_timeout("illuminance", timeout, [this]() { this->read_data_(); });
65}
66
67float TSL2561Sensor::calculate_lx_(uint16_t ch0, uint16_t ch1) {
68 if ((ch0 == 0xFFFF) || (ch1 == 0xFFFF)) {
69 ESP_LOGW(TAG, "Sensor is saturated");
70 return NAN;
71 }
72
73 float d0 = ch0, d1 = ch1;
74 float ratio = d1 / d0;
75
76 float ms = this->get_integration_time_ms_();
77 d0 *= (402.0f / ms);
78 d1 *= (402.0f / ms);
79
80 if (this->gain_ == TSL2561_GAIN_1X) {
81 d0 *= 16;
82 d1 *= 16;
83 }
84
85 if (this->package_cs_) {
86 if (ratio < 0.52f) {
87 return 0.0315f * d0 - 0.0593f * d0 * powf(ratio, 1.4f);
88 } else if (ratio < 0.65f) {
89 return 0.0229f * d0 - 0.0291f * d1;
90 } else if (ratio < 0.80f) {
91 return 0.0157f * d0 - 0.0153f * d1;
92 } else if (ratio < 1.30f) {
93 return 0.00338f * d0 - 0.00260f * d1;
94 }
95
96 return 0.0f;
97 } else {
98 if (ratio < 0.5f) {
99 return 0.0304f * d0 - 0.062f * d0 * powf(ratio, 1.4f);
100 } else if (ratio < 0.61f) {
101 return 0.0224f * d0 - 0.031f * d1;
102 } else if (ratio < 0.80f) {
103 return 0.0128f * d0 - 0.0153f * d1;
104 } else if (ratio < 1.30f) {
105 return 0.00146f * d0 - 0.00112f * d1;
106 }
107 return 0.0f;
108 }
109}
111 uint16_t data1, data0;
112 if (!this->tsl2561_read_uint(TSL2561_WORD_BIT | TSL2561_REGISTER_DATA_1, &data1)) {
113 this->status_set_warning();
114 return;
115 }
116 if (!this->tsl2561_read_uint(TSL2561_WORD_BIT | TSL2561_REGISTER_DATA_0, &data0)) {
117 this->status_set_warning();
118 return;
119 }
120 // Power off
121 if (!this->tsl2561_write_byte(TSL2561_REGISTER_CONTROL, 0b00000000)) {
122 this->status_set_warning();
123 return;
124 }
125
126 float lx = this->calculate_lx_(data0, data1);
127 ESP_LOGD(TAG, "Got illuminance=%.1flx", lx);
128 this->publish_state(lx);
129 this->status_clear_warning();
130}
132 switch (this->integration_time_) {
134 return 13.7f;
136 return 100.0f;
138 return 402.0f;
139 }
140 return 0.0f;
141}
146void TSL2561Sensor::set_is_cs_package(bool package_cs) { this->package_cs_ = package_cs; }
148bool TSL2561Sensor::tsl2561_write_byte(uint8_t a_register, uint8_t value) {
149 return this->write_byte(a_register | TSL2561_COMMAND_BIT, value);
150}
151bool TSL2561Sensor::tsl2561_read_uint(uint8_t a_register, uint16_t *value) {
152 uint8_t data[2];
153 if (!this->read_bytes(a_register | TSL2561_COMMAND_BIT, data, 2))
154 return false;
155 const uint16_t hi = data[1];
156 const uint16_t lo = data[0];
157 *value = (hi << 8) | lo;
158 return true;
159}
160bool TSL2561Sensor::tsl2561_read_byte(uint8_t a_register, uint8_t *value) {
161 return this->read_byte(a_register | TSL2561_COMMAND_BIT, value);
162}
163
164} // namespace tsl2561
165} // namespace esphome
virtual void mark_failed()
Mark this component as failed.
bool is_failed() const
void status_set_warning(const char *message=nullptr)
void status_clear_warning()
void set_timeout(const std::string &name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a unique name.
bool write_byte(uint8_t a_register, uint8_t data, bool stop=true)
Definition i2c.h:266
bool read_byte(uint8_t a_register, uint8_t *data, bool stop=true)
Definition i2c.h:239
bool read_bytes(uint8_t a_register, uint8_t *data, uint8_t len)
Compat APIs All methods below have been added for compatibility reasons.
Definition i2c.h:216
void publish_state(float state)
Publish a new state to the front-end.
Definition sensor.cpp:45
TSL2561IntegrationTime integration_time_
Definition tsl2561.h:81
bool tsl2561_write_byte(uint8_t a_register, uint8_t value)
Definition tsl2561.cpp:148
bool tsl2561_read_uint(uint8_t a_register, uint16_t *value)
Definition tsl2561.cpp:151
float calculate_lx_(uint16_t ch0, uint16_t ch1)
Definition tsl2561.cpp:67
bool tsl2561_read_byte(uint8_t a_register, uint8_t *value)
Definition tsl2561.cpp:160
float get_setup_priority() const override
Definition tsl2561.cpp:147
void set_gain(TSL2561Gain gain)
Set the internal gain of the sensor.
Definition tsl2561.cpp:145
void set_is_cs_package(bool package_cs)
The "CS" package of this sensor has a slightly different formula for converting the raw values.
Definition tsl2561.cpp:146
void set_integration_time(TSL2561IntegrationTime integration_time)
Set the time that sensor values should be accumulated for.
Definition tsl2561.cpp:142
AlsGain501 gain
IntegrationTime501 integration_time
const float DATA
For components that import data from directly connected sensors like DHT.
Definition component.cpp:50
TSL2561IntegrationTime
Enum listing all conversion/integration time settings for the TSL2561.
Definition tsl2561.h:14
@ TSL2561_INTEGRATION_14MS
Definition tsl2561.h:15
@ TSL2561_INTEGRATION_402MS
Definition tsl2561.h:17
@ TSL2561_INTEGRATION_101MS
Definition tsl2561.h:16
TSL2561Gain
Enum listing all gain settings for the TSL2561.
Definition tsl2561.h:24
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
T id(T value)
Helper function to make id(var) known from lambdas work in custom components.
Definition helpers.h:933