ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
apds9306.cpp
Go to the documentation of this file.
1// Based on this datasheet:
2// https://www.mouser.ca/datasheet/2/678/AVGO_S_A0002854364_1-2574547.pdf
3
4#include "apds9306.h"
6#include "esphome/core/log.h"
7
9
10ESPHOME_LOG_TAG(TAG, "apds9306");
11
12enum { // APDS9306 registers
18 APDS9306_CLEAR_DATA_0 = 0x0A, // LSB
20 APDS9306_CLEAR_DATA_2 = 0x0C, // MSB
21 APDS9306_ALS_DATA_0 = 0x0D, // LSB
23 APDS9306_ALS_DATA_2 = 0x0F, // MSB
33};
34
35#define APDS9306_ERROR_CHECK(func, error) \
36 if (!(func)) { \
37 this->mark_failed(LOG_STR(error)); \
38 return; \
39 }
40#define APDS9306_WARNING_CHECK(func, warning) \
41 if (!(func)) { \
42 ESP_LOGW(TAG, warning); \
43 this->status_set_warning(); \
44 return; \
45 }
46#define APDS9306_WRITE_BYTE(reg, value) \
47 ESP_LOGV(TAG, "Writing 0x%02x to 0x%02x", value, reg); \
48 if (!this->write_byte(reg, value)) { \
49 ESP_LOGE(TAG, "Failed writing 0x%02x to 0x%02x", value, reg); \
50 this->mark_failed(LOG_STR(ESP_LOG_MSG_COMM_FAIL)); \
51 return; \
52 }
53
55 // 0xB1 for APDS9306, 0xB3 for APDS9306-065; they differ only in bit 1
56 if (!this->check_chip_id(this, APDS9306_PART_ID, 0xB1, 0xFD))
57 return;
58
59 // ALS resolution and measurement, see datasheet or init.py for options
60 uint8_t als_meas_rate = ((this->bit_width_ & 0x07) << 4) | (this->measurement_rate_ & 0x07);
61 APDS9306_WRITE_BYTE(APDS9306_ALS_MEAS_RATE, als_meas_rate);
62
63 // ALS gain, see datasheet or init.py for options
64 uint8_t als_gain = (this->gain_ & 0x07);
65 APDS9306_WRITE_BYTE(APDS9306_ALS_GAIN, als_gain);
66
67 // Set to standby mode
68 APDS9306_WRITE_BYTE(APDS9306_MAIN_CTRL, 0x00);
69
70 // Check for data, clear main status
71 uint8_t status;
72 APDS9306_WARNING_CHECK(this->read_byte(APDS9306_MAIN_STATUS, &status), "Reading MAIN STATUS failed.");
73
74 // Set to active mode
75 APDS9306_WRITE_BYTE(APDS9306_MAIN_CTRL, 0x02);
76}
77
79 LOG_SENSOR("", "APDS9306", this);
80 LOG_I2C_DEVICE(this);
81
82 ESP_LOGCONFIG(TAG,
83 " Gain: %u\n"
84 " Measurement rate: %u\n"
85 " Measurement Resolution/Bit width: %d",
86 AMBIENT_LIGHT_GAIN_VALUES[this->gain_], MEASUREMENT_RATE_VALUES[this->measurement_rate_],
87 MEASUREMENT_BIT_WIDTH_VALUES[this->bit_width_]);
88
89 LOG_UPDATE_INTERVAL(this);
90}
91
93 // Check for new data
94 uint8_t status;
95 APDS9306_WARNING_CHECK(this->read_byte(APDS9306_MAIN_STATUS, &status), "Reading MAIN STATUS failed.");
96
98
99 status &= 0b00001000;
100 if (!status) { // No new data
101 return;
102 }
103
104 // Set to standby mode
105 APDS9306_WRITE_BYTE(APDS9306_MAIN_CTRL, 0x00);
106
107 // Clear MAIN STATUS
108 APDS9306_WARNING_CHECK(this->read_byte(APDS9306_MAIN_STATUS, &status), "Reading MAIN STATUS failed.");
109
110 uint8_t als_data[3];
111 APDS9306_WARNING_CHECK(this->read_bytes(APDS9306_ALS_DATA_0, als_data, 3), "Reading ALS data has failed.");
112
113 // Set to active mode
114 APDS9306_WRITE_BYTE(APDS9306_MAIN_CTRL, 0x02);
115
116 uint32_t light_level = 0x00 | encode_uint24(als_data[2], als_data[1], als_data[0]);
117
118 float lux = ((float) light_level / AMBIENT_LIGHT_GAIN_VALUES[this->gain_]) *
119 (100.0f / MEASUREMENT_RATE_VALUES[this->measurement_rate_]);
120
121 ESP_LOGD(TAG, "Got illuminance=%.1flx from", lux);
122 this->publish_state(lux);
123}
124
125} // namespace esphome::apds9306
uint8_t status
Definition bl0942.h:8
void status_clear_warning()
Definition component.h:296
MeasurementBitWidth bit_width_
Definition apds9306.h:53
AmbientLightGain gain_
Definition apds9306.h:55
void dump_config() override
Definition apds9306.cpp:78
MeasurementRate measurement_rate_
Definition apds9306.h:54
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_byte(uint8_t a_register, uint8_t *data)
Definition i2c.h:272
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:249
void publish_state(float state)
Publish a new state to the front-end.
Definition sensor.cpp:65
ESPHOME_LOG_TAG(TAG, "apds9306")
constexpr uint32_t encode_uint24(uint8_t byte1, uint8_t byte2, uint8_t byte3)
Encode a 24-bit value given three bytes in most to least significant byte order.
Definition helpers.h:1002
static void uint32_t