7static const char *
const TAG =
"apds9960";
9#define APDS9960_ERROR_CHECK(func) \
11 this->mark_failed(); \
14#define APDS9960_WRITE_BYTE(reg, value) APDS9960_ERROR_CHECK(this->write_byte(reg, value));
24 if (
id != 0xAB &&
id != 0x9C &&
id != 0xA8 &&
id != 0x9E) {
31 APDS9960_WRITE_BYTE(0x81, 0xDB);
33 APDS9960_WRITE_BYTE(0x83, 0xF6);
35 APDS9960_WRITE_BYTE(0x8E, 0x87);
37 APDS9960_WRITE_BYTE(0x9D, 0x00);
39 APDS9960_WRITE_BYTE(0x9E, 0x00);
41 APDS9960_WRITE_BYTE(0x8D, 0x60);
45 APDS9960_ERROR_CHECK(this->
read_byte(0x8F, &val));
57 APDS9960_WRITE_BYTE(0x8F,
val);
60 APDS9960_WRITE_BYTE(0x8C, 0x11);
62 APDS9960_WRITE_BYTE(0x90, 0x01);
64 APDS9960_WRITE_BYTE(0x9F, 0x00);
66 APDS9960_WRITE_BYTE(0xA0, 0x28);
68 APDS9960_WRITE_BYTE(0xA1, 0x1E);
71 APDS9960_WRITE_BYTE(0xA2, 0x40);
74 APDS9960_ERROR_CHECK(this->
read_byte(0xA3, &val));
88 APDS9960_WRITE_BYTE(0xA3,
val);
91 APDS9960_WRITE_BYTE(0xA4, 0x00);
93 APDS9960_WRITE_BYTE(0xA5, 0x00);
95 APDS9960_WRITE_BYTE(0xA7, 0x00);
97 APDS9960_WRITE_BYTE(0xA9, 0x00);
99 APDS9960_WRITE_BYTE(0xA6, 0xC9);
103 APDS9960_WRITE_BYTE(0xAA, 0x00);
114 APDS9960_WRITE_BYTE(0x80,
val);
118 return this->red_sensor_ !=
nullptr || this->green_sensor_ !=
nullptr || this->blue_sensor_ !=
nullptr ||
119 this->clear_sensor_ !=
nullptr;
125void APDS9960::dump_config() {
126 ESP_LOGCONFIG(TAG,
"APDS9960:");
127 LOG_I2C_DEVICE(
this);
129 LOG_UPDATE_INTERVAL(
this);
132 LOG_SENSOR(
" ",
"Red channel", this->red_sensor_);
133 LOG_SENSOR(
" ",
"Green channel", this->green_sensor_);
134 LOG_SENSOR(
" ",
"Blue channel", this->blue_sensor_);
135 LOG_SENSOR(
" ",
"Clear channel", this->clear_sensor_);
136 LOG_SENSOR(
" ",
"Proximity", this->proximity_sensor_);
140 switch (this->error_code_) {
142 ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
145 ESP_LOGE(TAG,
"APDS9960 has invalid id!");
148 ESP_LOGE(TAG,
"Setting up APDS9960 registers failed!");
154#define APDS9960_WARNING_CHECK(func, warning) \
156 ESP_LOGW(TAG, warning); \
157 this->status_set_warning(); \
161void APDS9960::update() {
163 APDS9960_WARNING_CHECK(this->
read_byte(0x93, &status),
"Reading status bit failed.");
176 if ((status & 0x01) == 0x00) {
182 APDS9960_WARNING_CHECK(this->
read_bytes(0x94, raw, 8),
"Reading color values failed.");
184 uint16_t uint_clear = (uint16_t(
raw[1]) << 8) |
raw[0];
185 uint16_t uint_red = (uint16_t(
raw[3]) << 8) |
raw[2];
186 uint16_t uint_green = (uint16_t(
raw[5]) << 8) |
raw[4];
187 uint16_t uint_blue = (uint16_t(
raw[7]) << 8) |
raw[6];
189 float clear_perc = (uint_clear / float(UINT16_MAX)) * 100.0f;
190 float red_perc = (uint_red / float(UINT16_MAX)) * 100.0f;
191 float green_perc = (uint_green / float(UINT16_MAX)) * 100.0f;
192 float blue_perc = (uint_blue / float(UINT16_MAX)) * 100.0f;
194 ESP_LOGD(TAG,
"Got clear=%.1f%% red=%.1f%% green=%.1f%% blue=%.1f%%", clear_perc, red_perc, green_perc, blue_perc);
196 if (this->clear_sensor_ !=
nullptr)
197 this->clear_sensor_->publish_state(clear_perc);
198 if (this->red_sensor_ !=
nullptr)
199 this->red_sensor_->publish_state(red_perc);
200 if (this->green_sensor_ !=
nullptr)
201 this->green_sensor_->publish_state(green_perc);
202 if (this->blue_sensor_ !=
nullptr)
203 this->blue_sensor_->publish_state(blue_perc);
210 if (this->proximity_sensor_ ==
nullptr)
213 if ((
status & 0b10) == 0x00) {
219 APDS9960_WARNING_CHECK(this->
read_byte(0x9C, &prox),
"Reading proximity values failed.");
221 float prox_perc = (prox / float(UINT8_MAX)) * 100.0f;
222 ESP_LOGD(TAG,
"Got proximity=%.1f%%", prox_perc);
223 this->proximity_sensor_->publish_state(prox_perc);
231 APDS9960_WARNING_CHECK(this->
read_byte(0xAF, &status),
"Reading gesture status failed.");
233 if ((
status & 0b01) == 0) {
238 if ((
status & 0b10) == 0b10) {
239 ESP_LOGV(TAG,
"FIFO buffer has filled to capacity!");
243 APDS9960_WARNING_CHECK(this->
read_byte(0xAE, &fifo_level),
"Reading FIFO level failed.");
244 if (fifo_level == 0) {
249 APDS9960_WARNING_CHECK(fifo_level <= 32,
"FIFO level has invalid value.")
252 for (uint8_t
pos = 0;
pos < fifo_level * 4;
pos += 32) {
256 uint8_t
read = std::min(32, fifo_level * 4 -
pos);
257 APDS9960_WARNING_CHECK(this->
read_bytes(0xFC, buf +
pos,
read),
"Reading FIFO buffer failed.");
267 for (
uint32_t i = 0; i < fifo_level * 4; i += 4) {
268 const int up = buf[i + 0];
269 const int down = buf[i + 1];
270 const int left = buf[i + 2];
271 const int right = buf[i + 3];
276#ifdef USE_BINARY_SENSOR
280 bin = this->up_direction_binary_sensor_;
283 ESP_LOGD(TAG,
"Got gesture UP");
286 bin = this->down_direction_binary_sensor_;
289 ESP_LOGD(TAG,
"Got gesture DOWN");
292 bin = this->left_direction_binary_sensor_;
295 ESP_LOGD(TAG,
"Got gesture LEFT");
298 bin = this->right_direction_binary_sensor_;
301 ESP_LOGD(TAG,
"Got gesture RIGHT");
307 if (bin !=
nullptr) {
337 const int up_down_delta = up - down;
338 const int left_right_delta = left - right;
339 const bool up_down_significant = abs(up_down_delta) > 13;
340 const bool left_right_significant = abs(left_right_delta) > 13;
342 if (up_down_significant) {
343 if (up_down_delta < 0) {
364 if (left_right_significant) {
365 if (left_right_delta < 0) {
389 this->proximity_sensor_ !=
nullptr
396#ifdef USE_BINARY_SENSOR
397 return this->up_direction_binary_sensor_ !=
nullptr || this->left_direction_binary_sensor_ !=
nullptr ||
398 this->down_direction_binary_sensor_ !=
nullptr || this->right_direction_binary_sensor_ !=
nullptr;