ESPHome 2026.5.0b1
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
10static const char *const 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 ESP_LOGE(TAG, error); \
38 this->mark_failed(); \
39 return; \
40 }
41#define APDS9306_WARNING_CHECK(func, warning) \
42 if (!(func)) { \
43 ESP_LOGW(TAG, warning); \
44 this->status_set_warning(); \
45 return; \
46 }
47#define APDS9306_WRITE_BYTE(reg, value) \
48 ESP_LOGV(TAG, "Writing 0x%02x to 0x%02x", value, reg); \
49 if (!this->write_byte(reg, value)) { \
50 ESP_LOGE(TAG, "Failed writing 0x%02x to 0x%02x", value, reg); \
51 this->mark_failed(); \
52 return; \
53 }
54
56 uint8_t id;
57 if (!this->read_byte(APDS9306_PART_ID, &id)) { // Part ID register
58 this->error_code_ = COMMUNICATION_FAILED;
59 this->mark_failed();
60 return;
61 }
62
63 if (id != 0xB1 && id != 0xB3) { // 0xB1 for APDS9306 0xB3 for APDS9306-065
64 this->error_code_ = WRONG_ID;
65 this->mark_failed();
66 return;
67 }
68
69 // ALS resolution and measurement, see datasheet or init.py for options
70 uint8_t als_meas_rate = ((this->bit_width_ & 0x07) << 4) | (this->measurement_rate_ & 0x07);
71 APDS9306_WRITE_BYTE(APDS9306_ALS_MEAS_RATE, als_meas_rate);
72
73 // ALS gain, see datasheet or init.py for options
74 uint8_t als_gain = (this->gain_ & 0x07);
75 APDS9306_WRITE_BYTE(APDS9306_ALS_GAIN, als_gain);
76
77 // Set to standby mode
78 APDS9306_WRITE_BYTE(APDS9306_MAIN_CTRL, 0x00);
79
80 // Check for data, clear main status
81 uint8_t status;
82 APDS9306_WARNING_CHECK(this->read_byte(APDS9306_MAIN_STATUS, &status), "Reading MAIN STATUS failed.");
83
84 // Set to active mode
85 APDS9306_WRITE_BYTE(APDS9306_MAIN_CTRL, 0x02);
86}
87
89 LOG_SENSOR("", "APDS9306", this);
90 LOG_I2C_DEVICE(this);
91
92 if (this->is_failed()) {
93 switch (this->error_code_) {
95 ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
96 break;
97 case WRONG_ID:
98 ESP_LOGE(TAG, "APDS9306 has invalid id!");
99 break;
100 default:
101 ESP_LOGE(TAG, "Setting up APDS9306 registers failed!");
102 break;
103 }
104 }
105
106 ESP_LOGCONFIG(TAG,
107 " Gain: %u\n"
108 " Measurement rate: %u\n"
109 " Measurement Resolution/Bit width: %d",
110 AMBIENT_LIGHT_GAIN_VALUES[this->gain_], MEASUREMENT_RATE_VALUES[this->measurement_rate_],
111 MEASUREMENT_BIT_WIDTH_VALUES[this->bit_width_]);
112
113 LOG_UPDATE_INTERVAL(this);
114}
115
117 // Check for new data
118 uint8_t status;
119 APDS9306_WARNING_CHECK(this->read_byte(APDS9306_MAIN_STATUS, &status), "Reading MAIN STATUS failed.");
120
121 this->status_clear_warning();
122
123 status &= 0b00001000;
124 if (!status) { // No new data
125 return;
126 }
127
128 // Set to standby mode
129 APDS9306_WRITE_BYTE(APDS9306_MAIN_CTRL, 0x00);
130
131 // Clear MAIN STATUS
132 APDS9306_WARNING_CHECK(this->read_byte(APDS9306_MAIN_STATUS, &status), "Reading MAIN STATUS failed.");
133
134 uint8_t als_data[3];
135 APDS9306_WARNING_CHECK(this->read_bytes(APDS9306_ALS_DATA_0, als_data, 3), "Reading ALS data has failed.");
136
137 // Set to active mode
138 APDS9306_WRITE_BYTE(APDS9306_MAIN_CTRL, 0x02);
139
140 uint32_t light_level = 0x00 | encode_uint24(als_data[2], als_data[1], als_data[0]);
141
142 float lux = ((float) light_level / AMBIENT_LIGHT_GAIN_VALUES[this->gain_]) *
143 (100.0f / MEASUREMENT_RATE_VALUES[this->measurement_rate_]);
144
145 ESP_LOGD(TAG, "Got illuminance=%.1flx from", lux);
146 this->publish_state(lux);
147}
148
149} // namespace esphome::apds9306
uint8_t status
Definition bl0942.h:8
void mark_failed()
Mark this component as failed.
bool is_failed() const
Definition component.h:284
void status_clear_warning()
Definition component.h:306
MeasurementBitWidth bit_width_
Definition apds9306.h:59
AmbientLightGain gain_
Definition apds9306.h:61
void dump_config() override
Definition apds9306.cpp:88
MeasurementRate measurement_rate_
Definition apds9306.h:60
bool read_byte(uint8_t a_register, uint8_t *data)
Definition i2c.h:240
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:217
void publish_state(float state)
Publish a new state to the front-end.
Definition sensor.cpp:68
uint16_t id
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:863
static void uint32_t