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