8static const char *
const TAG =
"apds9960";
10#define APDS9960_ERROR_CHECK(func) \
12 this->mark_failed(); \
15#define APDS9960_WRITE_BYTE(reg, value) APDS9960_ERROR_CHECK(this->write_byte(reg, value));
25 if (
id != 0xAB &&
id != 0x9C &&
id != 0xA8 &&
id != 0x9E) {
32 APDS9960_WRITE_BYTE(0x81, 0xDB);
34 APDS9960_WRITE_BYTE(0x83, 0xF6);
36 APDS9960_WRITE_BYTE(0x8E, 0x87);
38 APDS9960_WRITE_BYTE(0x9D, 0x00);
40 APDS9960_WRITE_BYTE(0x9E, 0x00);
42 APDS9960_WRITE_BYTE(0x8D, 0x60);
46 APDS9960_ERROR_CHECK(this->
read_byte(0x8F, &val));
58 APDS9960_WRITE_BYTE(0x8F,
val);
61 APDS9960_WRITE_BYTE(0x8C, 0x11);
63 APDS9960_WRITE_BYTE(0x90, 0x01);
65 APDS9960_WRITE_BYTE(0x9F, 0x00);
67 APDS9960_WRITE_BYTE(0xA0, 0x28);
69 APDS9960_WRITE_BYTE(0xA1, 0x1E);
72 APDS9960_WRITE_BYTE(0xA2, 0x40);
75 APDS9960_ERROR_CHECK(this->
read_byte(0xA3, &val));
89 APDS9960_WRITE_BYTE(0xA3,
val);
92 APDS9960_WRITE_BYTE(0xA4, 0x00);
94 APDS9960_WRITE_BYTE(0xA5, 0x00);
96 APDS9960_WRITE_BYTE(0xA7, 0x00);
98 APDS9960_WRITE_BYTE(0xA9, 0x00);
100 APDS9960_WRITE_BYTE(0xA6, 0xC9);
104 APDS9960_WRITE_BYTE(0xAA, 0x00);
115 APDS9960_WRITE_BYTE(0x80,
val);
119 return this->red_sensor_ !=
nullptr || this->green_sensor_ !=
nullptr || this->blue_sensor_ !=
nullptr ||
120 this->clear_sensor_ !=
nullptr;
126void APDS9960::dump_config() {
127 ESP_LOGCONFIG(TAG,
"APDS9960:");
128 LOG_I2C_DEVICE(
this);
130 LOG_UPDATE_INTERVAL(
this);
133 LOG_SENSOR(
" ",
"Red channel", this->red_sensor_);
134 LOG_SENSOR(
" ",
"Green channel", this->green_sensor_);
135 LOG_SENSOR(
" ",
"Blue channel", this->blue_sensor_);
136 LOG_SENSOR(
" ",
"Clear channel", this->clear_sensor_);
137 LOG_SENSOR(
" ",
"Proximity", this->proximity_sensor_);
141 switch (this->error_code_) {
143 ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
146 ESP_LOGE(TAG,
"APDS9960 has invalid id!");
149 ESP_LOGE(TAG,
"Setting up APDS9960 registers failed!");
155#define APDS9960_WARNING_CHECK(func, warning) \
157 ESP_LOGW(TAG, warning); \
158 this->status_set_warning(); \
162void APDS9960::update() {
164 APDS9960_WARNING_CHECK(this->
read_byte(0x93, &status),
"Reading status bit failed.");
177 if ((status & 0x01) == 0x00) {
183 APDS9960_WARNING_CHECK(this->
read_bytes(0x94, raw, 8),
"Reading color values failed.");
185 uint16_t uint_clear = (uint16_t(
raw[1]) << 8) |
raw[0];
186 uint16_t uint_red = (uint16_t(
raw[3]) << 8) |
raw[2];
187 uint16_t uint_green = (uint16_t(
raw[5]) << 8) |
raw[4];
188 uint16_t uint_blue = (uint16_t(
raw[7]) << 8) |
raw[6];
190 float clear_perc = (uint_clear / float(UINT16_MAX)) * 100.0f;
191 float red_perc = (uint_red / float(UINT16_MAX)) * 100.0f;
192 float green_perc = (uint_green / float(UINT16_MAX)) * 100.0f;
193 float blue_perc = (uint_blue / float(UINT16_MAX)) * 100.0f;
195 ESP_LOGD(TAG,
"Got clear=%.1f%% red=%.1f%% green=%.1f%% blue=%.1f%%", clear_perc, red_perc, green_perc, blue_perc);
197 if (this->clear_sensor_ !=
nullptr)
198 this->clear_sensor_->publish_state(clear_perc);
199 if (this->red_sensor_ !=
nullptr)
200 this->red_sensor_->publish_state(red_perc);
201 if (this->green_sensor_ !=
nullptr)
202 this->green_sensor_->publish_state(green_perc);
203 if (this->blue_sensor_ !=
nullptr)
204 this->blue_sensor_->publish_state(blue_perc);
211 if (this->proximity_sensor_ ==
nullptr)
214 if ((
status & 0b10) == 0x00) {
220 APDS9960_WARNING_CHECK(this->
read_byte(0x9C, &prox),
"Reading proximity values failed.");
222 float prox_perc = (prox / float(UINT8_MAX)) * 100.0f;
223 ESP_LOGD(TAG,
"Got proximity=%.1f%%", prox_perc);
224 this->proximity_sensor_->publish_state(prox_perc);
232 APDS9960_WARNING_CHECK(this->
read_byte(0xAF, &status),
"Reading gesture status failed.");
234 if ((
status & 0b01) == 0) {
239 if ((
status & 0b10) == 0b10) {
240 ESP_LOGV(TAG,
"FIFO buffer has filled to capacity!");
244 APDS9960_WARNING_CHECK(this->
read_byte(0xAE, &fifo_level),
"Reading FIFO level failed.");
245 if (fifo_level == 0) {
250 APDS9960_WARNING_CHECK(fifo_level <= 32,
"FIFO level has invalid value.")
253 for (uint8_t pos = 0; pos < fifo_level * 4; pos += 32) {
257 uint8_t
read = std::min(32, fifo_level * 4 - pos);
258 APDS9960_WARNING_CHECK(this->
read_bytes(0xFC + pos, buf + pos,
read),
"Reading FIFO buffer failed.");
268 for (uint32_t i = 0; i < fifo_level * 4; i += 4) {
269 const int up = buf[i + 0];
270 const int down = buf[i + 1];
271 const int left = buf[i + 2];
272 const int right = buf[i + 3];
277#ifdef USE_BINARY_SENSOR
281 bin = this->up_direction_binary_sensor_;
284 ESP_LOGD(TAG,
"Got gesture UP");
287 bin = this->down_direction_binary_sensor_;
290 ESP_LOGD(TAG,
"Got gesture DOWN");
293 bin = this->left_direction_binary_sensor_;
296 ESP_LOGD(TAG,
"Got gesture LEFT");
299 bin = this->right_direction_binary_sensor_;
302 ESP_LOGD(TAG,
"Got gesture RIGHT");
308 if (bin !=
nullptr) {
338 const int up_down_delta = up - down;
339 const int left_right_delta = left - right;
340 const bool up_down_significant = abs(up_down_delta) > 13;
341 const bool left_right_significant = abs(left_right_delta) > 13;
343 if (up_down_significant) {
344 if (up_down_delta < 0) {
365 if (left_right_significant) {
366 if (left_right_delta < 0) {
391 this->proximity_sensor_ !=
nullptr
398#ifdef USE_BINARY_SENSOR
399 return this->up_direction_binary_sensor_ !=
nullptr || this->left_direction_binary_sensor_ !=
nullptr ||
400 this->down_direction_binary_sensor_ !=
nullptr || this->right_direction_binary_sensor_ !=
nullptr;