ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
as7341.cpp
Go to the documentation of this file.
1#include "as7341.h"
2#include "esphome/core/log.h"
3#include "esphome/core/hal.h"
4
5namespace esphome::as7341 {
6
7ESPHOME_LOG_TAG(TAG, "as7341");
8
10 LOG_I2C_DEVICE(this);
11
12 if (!this->check_chip_id(this, AS7341_ID, AS7341_CHIP_ID << 2, 0xFC))
13 return;
14
15 // Power on (enter IDLE state)
16 if (!this->enable_power(true)) {
17 this->mark_failed(LOG_STR("Power on failed"));
18 return;
19 }
20
21 // Set configuration
22 this->write_byte(AS7341_CONFIG, 0x00);
23 this->setup_atime(this->atime_);
24 this->setup_astep(this->astep_);
25 this->setup_gain(this->gain_);
26}
27
29 ESP_LOGCONFIG(TAG, "AS7341:");
30 LOG_I2C_DEVICE(this);
31 LOG_UPDATE_INTERVAL(this);
32 ESP_LOGCONFIG(TAG,
33 " Gain: %u\n"
34 " ATIME: %u\n"
35 " ASTEP: %u",
37
38 LOG_SENSOR(" ", "F1", this->f1_);
39 LOG_SENSOR(" ", "F2", this->f2_);
40 LOG_SENSOR(" ", "F3", this->f3_);
41 LOG_SENSOR(" ", "F4", this->f4_);
42 LOG_SENSOR(" ", "F5", this->f5_);
43 LOG_SENSOR(" ", "F6", this->f6_);
44 LOG_SENSOR(" ", "F7", this->f7_);
45 LOG_SENSOR(" ", "F8", this->f8_);
46 LOG_SENSOR(" ", "Clear", this->clear_);
47 LOG_SENSOR(" ", "NIR", this->nir_);
48}
49
52
53 if (this->f1_ != nullptr) {
54 this->f1_->publish_state(this->channel_readings_[0]);
55 }
56 if (this->f2_ != nullptr) {
57 this->f2_->publish_state(this->channel_readings_[1]);
58 }
59 if (this->f3_ != nullptr) {
60 this->f3_->publish_state(this->channel_readings_[2]);
61 }
62 if (this->f4_ != nullptr) {
63 this->f4_->publish_state(this->channel_readings_[3]);
64 }
65 if (this->f5_ != nullptr) {
66 this->f5_->publish_state(this->channel_readings_[6]);
67 }
68 if (this->f6_ != nullptr) {
69 this->f6_->publish_state(this->channel_readings_[7]);
70 }
71 if (this->f7_ != nullptr) {
72 this->f7_->publish_state(this->channel_readings_[8]);
73 }
74 if (this->f8_ != nullptr) {
75 this->f8_->publish_state(this->channel_readings_[9]);
76 }
77 if (this->clear_ != nullptr) {
78 this->clear_->publish_state(this->channel_readings_[10]);
79 }
80 if (this->nir_ != nullptr) {
81 this->nir_->publish_state(this->channel_readings_[11]);
82 }
83}
84
86 uint8_t data;
87 this->read_byte(AS7341_CFG1, &data);
88 return (AS7341Gain) data;
89}
90
92 uint8_t data;
93 this->read_byte(AS7341_ATIME, &data);
94 return data;
95}
96
98 uint16_t data = 0;
99 this->read_byte_16_le(AS7341_ASTEP, &data);
100 return data;
101}
102
103bool AS7341Component::setup_gain(AS7341Gain gain) { return this->write_byte(AS7341_CFG1, gain); }
104
105bool AS7341Component::setup_atime(uint8_t atime) { return this->write_byte(AS7341_ATIME, atime); }
106
107bool AS7341Component::setup_astep(uint16_t astep) { return this->write_byte_16_le(AS7341_ASTEP, astep); }
108
109bool AS7341Component::read_channels(uint16_t *data) {
110 this->set_smux_low_channels(true);
111 this->enable_spectral_measurement(true);
112 this->wait_for_data();
113 bool low_success = this->read_bytes_16_le(AS7341_CH0_DATA_L, data, 6);
114
115 this->set_smux_low_channels(false);
116 this->enable_spectral_measurement(true);
117 this->wait_for_data();
118 bool high_sucess = this->read_bytes_16_le(AS7341_CH0_DATA_L, &data[6], 6);
119
120 return low_success && high_sucess;
121}
122
124 this->enable_spectral_measurement(false);
126
127 if (enable) {
129
130 } else {
132 }
133 this->enable_smux();
134}
135
137 uint8_t data = command << 3; // Write to bits 4:3 of the register
138 return this->write_byte(AS7341_CFG6, data);
139}
140
142 // SMUX Config for F1,F2,F3,F4,NIR,Clear
143 this->write_byte(0x00, 0x30); // F3 left set to ADC2
144 this->write_byte(0x01, 0x01); // F1 left set to ADC0
145 this->write_byte(0x02, 0x00); // Reserved or disabled
146 this->write_byte(0x03, 0x00); // F8 left disabled
147 this->write_byte(0x04, 0x00); // F6 left disabled
148 this->write_byte(0x05, 0x42); // F4 left connected to ADC3/f2 left connected to ADC1
149 this->write_byte(0x06, 0x00); // F5 left disbled
150 this->write_byte(0x07, 0x00); // F7 left disbled
151 this->write_byte(0x08, 0x50); // CLEAR connected to ADC4
152 this->write_byte(0x09, 0x00); // F5 right disabled
153 this->write_byte(0x0A, 0x00); // F7 right disabled
154 this->write_byte(0x0B, 0x00); // Reserved or disabled
155 this->write_byte(0x0C, 0x20); // F2 right connected to ADC1
156 this->write_byte(0x0D, 0x04); // F4 right connected to ADC3
157 this->write_byte(0x0E, 0x00); // F6/F8 right disabled
158 this->write_byte(0x0F, 0x30); // F3 right connected to AD2
159 this->write_byte(0x10, 0x01); // F1 right connected to AD0
160 this->write_byte(0x11, 0x50); // CLEAR right connected to AD4
161 this->write_byte(0x12, 0x00); // Reserved or disabled
162 this->write_byte(0x13, 0x06); // NIR connected to ADC5
163}
164
166 // SMUX Config for F5,F6,F7,F8,NIR,Clear
167 this->write_byte(0x00, 0x00); // F3 left disable
168 this->write_byte(0x01, 0x00); // F1 left disable
169 this->write_byte(0x02, 0x00); // reserved/disable
170 this->write_byte(0x03, 0x40); // F8 left connected to ADC3
171 this->write_byte(0x04, 0x02); // F6 left connected to ADC1
172 this->write_byte(0x05, 0x00); // F4/ F2 disabled
173 this->write_byte(0x06, 0x10); // F5 left connected to ADC0
174 this->write_byte(0x07, 0x03); // F7 left connected to ADC2
175 this->write_byte(0x08, 0x50); // CLEAR Connected to ADC4
176 this->write_byte(0x09, 0x10); // F5 right connected to ADC0
177 this->write_byte(0x0A, 0x03); // F7 right connected to ADC2
178 this->write_byte(0x0B, 0x00); // Reserved or disabled
179 this->write_byte(0x0C, 0x00); // F2 right disabled
180 this->write_byte(0x0D, 0x00); // F4 right disabled
181 this->write_byte(0x0E, 0x24); // F8 right connected to ADC2/ F6 right connected to ADC1
182 this->write_byte(0x0F, 0x00); // F3 right disabled
183 this->write_byte(0x10, 0x00); // F1 right disabled
184 this->write_byte(0x11, 0x50); // CLEAR right connected to AD4
185 this->write_byte(0x12, 0x00); // Reserved or disabled
186 this->write_byte(0x13, 0x06); // NIR connected to ADC5
187}
188
190 this->set_register_bit(AS7341_ENABLE, 4);
191
192 uint16_t timeout = 1000;
193 for (uint16_t time = 0; time < timeout; time++) {
194 // The SMUXEN bit is cleared once the SMUX operation is finished
195 bool smuxen = this->read_register_bit(AS7341_ENABLE, 4);
196 if (!smuxen) {
197 return true;
198 }
199
200 delay(1);
201 }
202
203 return false;
204}
205
207 uint16_t timeout = 1000;
208 for (uint16_t time = 0; time < timeout; time++) {
209 if (this->is_data_ready()) {
210 return true;
211 }
212
213 delay(1);
214 }
215
216 return false;
217}
218
219bool AS7341Component::is_data_ready() { return this->read_register_bit(AS7341_STATUS2, 6); }
220
221bool AS7341Component::enable_power(bool enable) { return this->write_register_bit(AS7341_ENABLE, enable, 0); }
222
224 return this->write_register_bit(AS7341_ENABLE, enable, 1);
225}
226
227bool AS7341Component::read_register_bit(uint8_t address, uint8_t bit_position) {
228 uint8_t data;
229 this->read_byte(address, &data);
230 bool bit = (data & (1 << bit_position)) > 0;
231 return bit;
232}
233
234bool AS7341Component::write_register_bit(uint8_t address, bool value, uint8_t bit_position) {
235 if (value) {
236 return this->set_register_bit(address, bit_position);
237 }
238
239 return this->clear_register_bit(address, bit_position);
240}
241
242bool AS7341Component::set_register_bit(uint8_t address, uint8_t bit_position) {
243 uint8_t data;
244 this->read_byte(address, &data);
245 data |= (1 << bit_position);
246 return this->write_byte(address, data);
247}
248
249bool AS7341Component::clear_register_bit(uint8_t address, uint8_t bit_position) {
250 uint8_t data;
251 this->read_byte(address, &data);
252 data &= ~(1 << bit_position);
253 return this->write_byte(address, data);
254}
255
256} // namespace esphome::as7341
uint8_t address
Definition bl0906.h:4
void mark_failed()
Mark this component as failed.
bool setup_atime(uint8_t atime)
Definition as7341.cpp:105
bool setup_gain(AS7341Gain gain)
Definition as7341.cpp:103
bool read_register_bit(uint8_t address, uint8_t bit_position)
Definition as7341.cpp:227
bool clear_register_bit(uint8_t address, uint8_t bit_position)
Definition as7341.cpp:249
bool enable_power(bool enable)
Definition as7341.cpp:221
bool read_channels(uint16_t *data)
Definition as7341.cpp:109
bool set_smux_command(AS7341SmuxCommand command)
Definition as7341.cpp:136
bool setup_astep(uint16_t astep)
Definition as7341.cpp:107
void set_smux_low_channels(bool enable)
Definition as7341.cpp:123
bool enable_spectral_measurement(bool enable)
Definition as7341.cpp:223
bool set_register_bit(uint8_t address, uint8_t bit_position)
Definition as7341.cpp:242
bool write_register_bit(uint8_t address, bool value, uint8_t bit_position)
Definition as7341.cpp:234
bool write_byte_16_le(uint8_t a_register, uint16_t data) const
Write a 16-bit value least significant byte first.
Definition i2c.cpp:106
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.
Definition i2c.h:232
bool read_bytes_16_le(uint8_t a_register, uint16_t *data, uint8_t len)
Read len 16-bit values stored least significant byte first; no conversion is compiled on little-endia...
Definition i2c.h:284
bool write_byte(uint8_t a_register, uint8_t data) const
Definition i2c.h:312
bool read_byte(uint8_t a_register, uint8_t *data)
Definition i2c.h:272
bool read_byte_16_le(uint8_t a_register, uint16_t *data)
Read a 16-bit value stored least significant byte first.
Definition i2c.h:296
void publish_state(float state)
Publish a new state to the front-end.
Definition sensor.cpp:65
AlsGain501 gain
ESPHOME_LOG_TAG(TAG, "as7341")
@ AS7341_SMUX_CMD_WRITE
Write SMUX configuration from RAM to SMUX chain.
Definition as7341.h:59
void HOT delay(uint32_t ms)
Definition hal.cpp:85