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