ESPHome 2025.5.0
Loading...
Searching...
No Matches
veml3235.cpp
Go to the documentation of this file.
1#include "veml3235.h"
3#include "esphome/core/log.h"
4
5namespace esphome {
6namespace veml3235 {
7
8static const char *const TAG = "veml3235.sensor";
9
11 uint8_t device_id[] = {0, 0};
12
13 ESP_LOGCONFIG(TAG, "Setting up VEML3235 '%s'...", this->name_.c_str());
14
15 if (!this->refresh_config_reg()) {
16 ESP_LOGE(TAG, "Unable to write configuration");
17 this->mark_failed();
18 return;
19 }
20 if ((this->write(&ID_REG, 1, false) != i2c::ERROR_OK) || !this->read_bytes_raw(device_id, 2)) {
21 ESP_LOGE(TAG, "Unable to read ID");
22 this->mark_failed();
23 return;
24 } else if (device_id[0] != DEVICE_ID) {
25 ESP_LOGE(TAG, "Incorrect device ID - expected 0x%.2x, read 0x%.2x", DEVICE_ID, device_id[0]);
26 this->mark_failed();
27 return;
28 }
29}
30
32 uint16_t data = this->power_on_ || force_on ? 0 : SHUTDOWN_BITS;
33
34 data |= (uint16_t(this->integration_time_ << CONFIG_REG_IT_BIT));
35 data |= (uint16_t(this->digital_gain_ << CONFIG_REG_DG_BIT));
36 data |= (uint16_t(this->gain_ << CONFIG_REG_G_BIT));
37 data |= 0x1; // mandatory 1 here per RM
38
39 ESP_LOGVV(TAG, "Writing 0x%.4x to register 0x%.2x", data, CONFIG_REG);
40 return this->write_byte_16(CONFIG_REG, data);
41}
42
44 if (!this->power_on_) { // if off, turn on
45 if (!this->refresh_config_reg(true)) {
46 ESP_LOGW(TAG, "Turning on failed");
47 this->status_set_warning();
48 return NAN;
49 }
50 delay(4); // from RM: a wait time of 4 ms should be observed before the first measurement is picked up, to allow
51 // for a correct start of the signal processor and oscillator
52 }
53
54 uint8_t als_regs[] = {0, 0};
55 if ((this->write(&ALS_REG, 1, false) != i2c::ERROR_OK) || !this->read_bytes_raw(als_regs, 2)) {
56 this->status_set_warning();
57 return NAN;
58 }
59
61
62 float als_raw_value_multiplier = LUX_MULTIPLIER_BASE;
63 uint16_t als_raw_value = encode_uint16(als_regs[1], als_regs[0]);
64 // determine multiplier value based on gains and integration time
66 als_raw_value_multiplier *= 2;
67 }
68 switch (this->gain_) {
70 als_raw_value_multiplier *= 4;
71 break;
73 als_raw_value_multiplier *= 2;
74 break;
75 default:
76 break;
77 }
78 switch (this->integration_time_) {
80 als_raw_value_multiplier *= 16;
81 break;
83 als_raw_value_multiplier *= 8;
84 break;
86 als_raw_value_multiplier *= 4;
87 break;
89 als_raw_value_multiplier *= 2;
90 break;
91 default:
92 break;
93 }
94 // finally, determine and return the actual lux value
95 float lx = float(als_raw_value) * als_raw_value_multiplier;
96 ESP_LOGVV(TAG, "'%s': ALS raw = %u, multiplier = %.5f", this->get_name().c_str(), als_raw_value,
97 als_raw_value_multiplier);
98 ESP_LOGD(TAG, "'%s': Illuminance = %.4flx", this->get_name().c_str(), lx);
99
100 if (!this->power_on_) { // turn off if required
101 if (!this->refresh_config_reg()) {
102 ESP_LOGW(TAG, "Turning off failed");
103 this->status_set_warning();
104 }
105 }
106
107 if (this->auto_gain_) {
108 this->adjust_gain_(als_raw_value);
109 }
110
111 return lx;
112}
113
114void VEML3235Sensor::adjust_gain_(const uint16_t als_raw_value) {
115 if ((als_raw_value > UINT16_MAX * this->auto_gain_threshold_low_) &&
116 (als_raw_value < UINT16_MAX * this->auto_gain_threshold_high_)) {
117 return;
118 }
119
120 if (als_raw_value >= UINT16_MAX * 0.9) { // over-saturated, reset all gains and start over
122 this->gain_ = VEML3235_GAIN_1X;
124 this->refresh_config_reg();
125 return;
126 }
127
128 if (this->gain_ != VEML3235_GAIN_4X) { // increase gain if possible
129 switch (this->gain_) {
130 case VEML3235_GAIN_1X:
131 this->gain_ = VEML3235_GAIN_2X;
132 break;
133 case VEML3235_GAIN_2X:
134 this->gain_ = VEML3235_GAIN_4X;
135 break;
136 default:
137 break;
138 }
139 this->refresh_config_reg();
140 return;
141 }
142 // gain is maxed out; reset it and try to increase digital gain
143 if (this->digital_gain_ != VEML3235_DIGITAL_GAIN_2X) { // increase digital gain if possible
145 this->gain_ = VEML3235_GAIN_1X;
146 this->refresh_config_reg();
147 return;
148 }
149 // digital gain is maxed out; reset it and try to increase integration time
150 if (this->integration_time_ != VEML3235_INTEGRATION_TIME_800MS) { // increase integration time if possible
151 switch (this->integration_time_) {
154 break;
157 break;
160 break;
163 break;
164 default:
165 break;
166 }
168 this->gain_ = VEML3235_GAIN_1X;
169 this->refresh_config_reg();
170 return;
171 }
172}
173
175 uint8_t digital_gain = 1;
176 uint8_t gain = 1;
177 uint16_t integration_time = 0;
178
180 digital_gain = 2;
181 }
182 switch (this->gain_) {
183 case VEML3235_GAIN_2X:
184 gain = 2;
185 break;
186 case VEML3235_GAIN_4X:
187 gain = 4;
188 break;
189 default:
190 break;
191 }
192 switch (this->integration_time_) {
194 integration_time = 50;
195 break;
197 integration_time = 100;
198 break;
200 integration_time = 200;
201 break;
203 integration_time = 400;
204 break;
206 integration_time = 800;
207 break;
208 default:
209 break;
210 }
211
212 LOG_SENSOR("", "VEML3235", this);
213 LOG_I2C_DEVICE(this);
214 if (this->is_failed()) {
215 ESP_LOGE(TAG, "Communication failed");
216 }
217 LOG_UPDATE_INTERVAL(this);
218 ESP_LOGCONFIG(TAG, " Auto-gain enabled: %s", YESNO(this->auto_gain_));
219 if (this->auto_gain_) {
220 ESP_LOGCONFIG(TAG, " Auto-gain upper threshold: %f%%", this->auto_gain_threshold_high_ * 100.0);
221 ESP_LOGCONFIG(TAG, " Auto-gain lower threshold: %f%%", this->auto_gain_threshold_low_ * 100.0);
222 ESP_LOGCONFIG(TAG, " Values below will be used as initial values only");
223 }
224 ESP_LOGCONFIG(TAG, " Digital gain: %uX", digital_gain);
225 ESP_LOGCONFIG(TAG, " Gain: %uX", gain);
226 ESP_LOGCONFIG(TAG, " Integration time: %ums", integration_time);
227}
228
229} // namespace veml3235
230} // namespace esphome
virtual void mark_failed()
Mark this component as failed.
bool is_failed() const
void status_set_warning(const char *message="unspecified")
void status_clear_warning()
const StringRef & get_name() const
constexpr const char * c_str() const
Definition string_ref.h:68
ErrorCode write(const uint8_t *data, size_t len, bool stop=true)
writes an array of bytes to a device using an I2CBus
Definition i2c.h:190
optional< std::array< uint8_t, N > > read_bytes_raw()
Definition i2c.h:229
bool write_byte_16(uint8_t a_register, uint16_t data)
Definition i2c.h:270
VEML3235ComponentIntegrationTime integration_time_
Definition veml3235.h:105
VEML3235ComponentGain gain()
Definition veml3235.h:89
void adjust_gain_(uint16_t als_raw_value)
Definition veml3235.cpp:114
VEML3235ComponentIntegrationTime integration_time()
Definition veml3235.h:90
VEML3235ComponentGain gain_
Definition veml3235.h:104
VEML3235ComponentDigitalGain digital_gain()
Definition veml3235.h:88
VEML3235ComponentDigitalGain digital_gain_
Definition veml3235.h:103
bool refresh_config_reg(bool force_on=false)
Definition veml3235.cpp:31
@ ERROR_OK
No error found during execution of method.
Definition i2c_bus.h:13
@ VEML3235_INTEGRATION_TIME_100MS
Definition veml3235.h:40
@ VEML3235_INTEGRATION_TIME_200MS
Definition veml3235.h:41
@ VEML3235_INTEGRATION_TIME_50MS
Definition veml3235.h:39
@ VEML3235_INTEGRATION_TIME_800MS
Definition veml3235.h:43
@ VEML3235_INTEGRATION_TIME_400MS
Definition veml3235.h:42
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
constexpr uint16_t encode_uint16(uint8_t msb, uint8_t lsb)
Encode a 16-bit value given the most and least significant byte.
Definition helpers.h:191
void IRAM_ATTR HOT delay(uint32_t ms)
Definition core.cpp:28