ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
as734x.h
Go to the documentation of this file.
1#pragma once
2
3#include <array>
4#include <cstdint>
5
7#include "esphome/core/hal.h"
10#ifdef USE_AS734X_RGB
12#endif
13
14namespace esphome::as734x {
15
31
32static constexpr uint8_t GAIN_COUNT = 13; // entries in Gain, for sizing the correction tables
33static constexpr uint8_t NUM_BANDS = 13; // band order of BANDS_43 in __init__.py
34
35// What the published basic counts are divided by. The clear channel is wideband, so it is roughly
36// the size of all the bands together, and the near infrared channel outgrows them under daylight.
37// Dividing by the largest of every channel therefore leaves the visible bands squeezed into the
38// bottom of the range.
39enum class Normalization : uint8_t {
40 NORMALIZATION_NONE, // publish absolute basic counts
41 NORMALIZATION_ALL, // largest of every channel
42 NORMALIZATION_BANDS, // largest of the visible bands only
43 NORMALIZATION_CLEAR, // the wideband clear channel
44};
45
46// Nominal centre wavelengths in nanometres bound the visible bands. The clear channel is wideband
47// and has no single centre wavelength, so it is marked with zero instead.
48static constexpr uint16_t VISIBLE_MIN_NM = 380;
49static constexpr uint16_t VISIBLE_MAX_NM = 700;
50static constexpr uint16_t WIDEBAND_NM = 0;
51static constexpr uint16_t ABSENT_NM = 0xFFFF; // band this chip does not have
52
53// Luminous efficacy at 555 nm, for turning photopic irradiance into lux.
54static constexpr float LUMENS_PER_WATT = 683.002f;
55
56// How much one basic count of a band contributes to each integrated quantity. The factors come
57// from the manufacturer's golden-device calibration, convolved for a reconstructed spectrum.
59 float irradiance_photopic; // weighted by the CIE 1931 V(lambda) curve
60 float irradiance_par; // 400-700 nm only
61 float ppfd; // 400-700 nm only, scaled by 1e3 before publishing
62};
63
64// CIE 1931 tristimulus contribution of one basic count of a band.
66 float x;
67 float y;
68 float z;
69};
70
71struct RegValue {
72 uint8_t reg;
73 uint8_t value;
74};
75
77struct ChipInfo {
78 const char *name;
79 const RegValue *init; // written in order; the bank is selected per register address
80 const uint8_t *smux; // AS7341: SMUX RAM image per step; AS7343: the three chain images
81 const uint8_t *readout; // per step, the ADC slot of each band (0xFF: not read in this step)
82 const uint16_t *wavelengths; // per band, WIDEBAND_NM for clear and ABSENT_NM for a missing band
83 const float *gain_correction; // GAIN_COUNT entries, or GAIN_COUNT * NUM_BANDS when per band
85 const ChannelTristimulus *tristimulus; // per band
86 uint8_t init_count;
87 uint8_t astep_reg;
88 uint8_t cfg0_reg;
89 uint8_t cfg1_reg;
90 uint8_t status2_reg;
91 uint8_t id_reg;
92 uint8_t id_mask;
93 uint8_t id_value;
94 uint8_t led_reg; // LED driver register (0: this chip has no LED control)
95 uint8_t led_sel_reg; // register whose LED_SEL bit hands the pin to the driver (0: not needed)
96 uint8_t adc_slots; // 16-bit data registers read after ASTATUS
97 uint8_t smux_steps; // measurements per update
99 uint8_t smux_len; // bytes per SMUX image
100 bool auto_smux; // the chip cycles its SMUX itself after a one-time chain setup
101 bool gain_correction_per_band; // the correction table is indexed by gain and band, not gain alone
102 uint8_t extra_clear_slot; // averaged into the clear band (0xFF: none)
103};
104
105#ifdef USE_AS7341
106extern const ChipInfo AS7341_CHIP;
107#endif
108#ifdef USE_AS7343
109extern const ChipInfo AS7343_CHIP;
110extern const ChipInfo TCS3448_CHIP;
111#endif
112
114 public:
115 // Channel correction is multiplicative, so it starts at unity rather than zero in case no
116 // calibration is configured.
117 explicit AS734XComponent(const ChipInfo *chip) : chip_(chip) { this->channel_correction_.fill(1.0f); }
118
119 void setup() override;
120 void dump_config() override;
121 void update() override;
122 void loop() override;
123
124 void set_gain(Gain gain) { this->gain_ = gain; }
125 void set_atime(uint8_t atime) { this->atime_ = atime; }
126 void set_astep(uint16_t astep) { this->astep_ = astep; }
127
129 void enable_led(bool enable);
130
131 // Calibration applied while turning raw counts into basic counts.
132 void set_dark_current(const std::array<float, NUM_BANDS> &values) { this->dark_current_ = values; }
133 void set_channel_correction(const std::array<float, NUM_BANDS> &values) { this->channel_correction_ = values; }
134 void set_glass_attenuation_factor(float factor) { this->glass_attenuation_factor_ = factor; }
135
137 void set_basic_counts_normalization(Normalization normalization) { this->normalization_ = normalization; }
138
139 void set_counts_sensor(sensor::Sensor *sensor, uint8_t band) { this->sensors_[band] = sensor; }
140 void set_basic_counts_sensor(sensor::Sensor *sensor, uint8_t band) { this->basic_counts_sensors_[band] = sensor; }
141
142 SUB_SENSOR(saturation_level)
143 SUB_SENSOR(illuminance)
144 SUB_SENSOR(irradiance_photopic)
145 SUB_SENSOR(irradiance_par)
146 SUB_SENSOR(ppfd)
147 SUB_SENSOR(color_temperature)
148
149#ifdef USE_AS734X_RGB
150 void set_rgb_hex_sensor(text_sensor::TextSensor *sensor) { this->rgb_hex_sensor_ = sensor; }
151#endif
152
153 protected:
154 bool select_bank_(uint8_t reg);
155 bool update_bits_(uint8_t reg, uint8_t mask, bool value);
156 bool write_exposure_();
157 bool start_step_();
158 void read_step_();
159 void abort_measurement_(const LogString *reason);
162 void publish_color_();
165 float normalization_divisor_() const;
166
167 std::array<sensor::Sensor *, NUM_BANDS> sensors_{};
168 std::array<sensor::Sensor *, NUM_BANDS> basic_counts_sensors_{};
169 std::array<float, NUM_BANDS> dark_current_{};
170 std::array<float, NUM_BANDS> channel_correction_;
171 std::array<float, NUM_BANDS> basic_counts_{};
172 std::array<uint16_t, NUM_BANDS> raw_counts_{};
173 const ChipInfo *chip_; // in flash, read field by field with progmem_memcpy
178 float max_basic_count_{0.0f}; // largest of every channel
179 float max_band_basic_count_{0.0f}; // largest of the visible bands only
180 float clear_basic_count_{0.0f}; // the wideband clear channel
181 uint16_t astep_{0};
182 uint16_t peak_raw_count_{0}; // highest ADC value of this measurement, before the clear channels are averaged
183 // What the running measurement was started with, so the maths matches the data even if the
184 // configuration is changed while a measurement is in flight.
185 uint16_t reading_astep_{0};
187 uint8_t reading_atime_{0};
191 uint8_t atime_{0};
192 uint8_t step_{0};
193 bool bank_low_{true}; // unknown until setup() writes CFG0
194#ifdef USE_AS734X_RGB
196#endif
197};
198
199} // namespace esphome::as734x
This class simplifies creating components that periodically check a state.
Definition component.h:514
void enable_led(bool enable)
Turns the sensor's LED driver on or off. Meant for lambdas.
Definition as734x.cpp:360
void set_channel_correction(const std::array< float, NUM_BANDS > &values)
Definition as734x.h:133
AS734XComponent(const ChipInfo *chip)
Definition as734x.h:117
SUB_SENSOR(saturation_level) SUB_SENSOR(illuminance) SUB_SENSOR(irradiance_photopic) SUB_SENSOR(irradiance_par) SUB_SENSOR(ppfd) SUB_SENSOR(color_temperature) void set_rgb_hex_sensor(text_sensor
Definition as734x.h:142
text_sensor::TextSensor * rgb_hex_sensor_
Definition as734x.h:195
void set_basic_counts_sensor(sensor::Sensor *sensor, uint8_t band)
Definition as734x.h:140
std::array< float, NUM_BANDS > channel_correction_
Definition as734x.h:170
std::array< float, NUM_BANDS > dark_current_
Definition as734x.h:169
void set_basic_counts_normalization(Normalization normalization)
Chooses what the published basic counts are divided by.
Definition as734x.h:137
void set_counts_sensor(sensor::Sensor *sensor, uint8_t band)
Definition as734x.h:139
void abort_measurement_(const LogString *reason)
Definition as734x.cpp:663
std::array< sensor::Sensor *, NUM_BANDS > basic_counts_sensors_
Definition as734x.h:168
bool select_bank_(uint8_t reg)
Definition as734x.cpp:257
bool update_bits_(uint8_t reg, uint8_t mask, bool value)
Definition as734x.cpp:266
std::array< uint16_t, NUM_BANDS > raw_counts_
Definition as734x.h:172
float normalization_divisor_() const
Definition as734x.cpp:536
void set_astep(uint16_t astep)
Definition as734x.h:126
void set_dark_current(const std::array< float, NUM_BANDS > &values)
Definition as734x.h:132
void set_atime(uint8_t atime)
Definition as734x.h:125
std::array< float, NUM_BANDS > basic_counts_
Definition as734x.h:171
std::array< sensor::Sensor *, NUM_BANDS > sensors_
Definition as734x.h:167
void set_glass_attenuation_factor(float factor)
Definition as734x.h:134
enum esphome::as734x::AS734XComponent::State STATE_IDLE
This Class provides the methods to read/write bytes from/to an i2c device.
Definition i2c.h:132
I2CRegister reg(uint8_t a_register)
calls the I2CRegister constructor
Definition i2c.h:152
Base-class for all sensors.
Definition sensor.h:47
AlsGain501 gain
const ChipInfo TCS3448_CHIP
const ChipInfo AS7341_CHIP
const ChipInfo AS7343_CHIP
static void uint32_t
Per-chip constants, stored in flash. The pointed-to tables are in flash too.
Definition as734x.h:77
const uint16_t * wavelengths
Definition as734x.h:82
const uint8_t * smux
Definition as734x.h:80
const ChannelTristimulus * tristimulus
Definition as734x.h:85
const char * name
Definition as734x.h:78
const RegValue * init
Definition as734x.h:79
const uint8_t * readout
Definition as734x.h:81
const ChannelContribution * contributions
Definition as734x.h:84
const float * gain_correction
Definition as734x.h:83