From e008b054cbf76d0271cba85f0e0574c7c3a07118 Mon Sep 17 00:00:00 2001 From: Samuel Sieb Date: Sun, 14 Aug 2022 15:16:56 -0700 Subject: [PATCH] support modifying the apds9960 settings (#3708) Co-authored-by: Samuel Sieb Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> --- esphome/components/apds9960/__init__.py | 41 ++++++++++++++++++++++++ esphome/components/apds9960/apds9960.cpp | 23 +++++++------ esphome/components/apds9960/apds9960.h | 14 ++++++++ 3 files changed, 66 insertions(+), 12 deletions(-) diff --git a/esphome/components/apds9960/__init__.py b/esphome/components/apds9960/__init__.py index 8de83251b7..37dc4c0b28 100644 --- a/esphome/components/apds9960/__init__.py +++ b/esphome/components/apds9960/__init__.py @@ -8,6 +8,27 @@ AUTO_LOAD = ["sensor", "binary_sensor"] MULTI_CONF = True CONF_APDS9960_ID = "apds9960_id" +CONF_LED_DRIVE = "led_drive" +CONF_PROXIMITY_GAIN = "proximity_gain" +CONF_AMBIENT_LIGHT_GAIN = "ambient_light_gain" +CONF_GESTURE_LED_DRIVE = "gesture_led_drive" +CONF_GESTURE_GAIN = "gesture_gain" +CONF_GESTURE_WAIT_TIME = "gesture_wait_time" + +DRIVE_LEVELS = {"100ma": 0, "50ma": 1, "25ma": 2, "12.5ma": 3} +PROXIMITY_LEVELS = {"1x": 0, "2x": 1, "4x": 2, "8x": 3} +AMBIENT_LEVELS = {"1x": 0, "4x": 1, "16x": 2, "64x": 3} +GESTURE_LEVELS = {"1x": 0, "2x": 1, "4x": 2, "8x": 3} +GESTURE_WAIT_TIMES = { + "0ms": 0, + "2.8ms": 1, + "5.6ms": 2, + "8.4ms": 3, + "14ms": 4, + "22.4ms": 5, + "30.8ms": 6, + "39.2ms": 7, +} apds9960_nds = cg.esphome_ns.namespace("apds9960") APDS9960 = apds9960_nds.class_("APDS9960", cg.PollingComponent, i2c.I2CDevice) @@ -16,6 +37,20 @@ CONFIG_SCHEMA = ( cv.Schema( { cv.GenerateID(): cv.declare_id(APDS9960), + cv.Optional(CONF_LED_DRIVE, "100mA"): cv.enum(DRIVE_LEVELS, lower=True), + cv.Optional(CONF_PROXIMITY_GAIN, "4x"): cv.enum( + PROXIMITY_LEVELS, lower=True + ), + cv.Optional(CONF_AMBIENT_LIGHT_GAIN, "4x"): cv.enum( + AMBIENT_LEVELS, lower=True + ), + cv.Optional(CONF_GESTURE_LED_DRIVE, "100mA"): cv.enum( + DRIVE_LEVELS, lower=True + ), + cv.Optional(CONF_GESTURE_GAIN, "4x"): cv.enum(GESTURE_LEVELS, lower=True), + cv.Optional(CONF_GESTURE_WAIT_TIME, "2.8ms"): cv.enum( + GESTURE_WAIT_TIMES, lower=True + ), } ) .extend(cv.polling_component_schema("60s")) @@ -27,3 +62,9 @@ async def to_code(config): var = cg.new_Pvariable(config[CONF_ID]) await cg.register_component(var, config) await i2c.register_i2c_device(var, config) + cg.add(var.set_led_drive(config[CONF_LED_DRIVE])) + cg.add(var.set_proximity_gain(config[CONF_PROXIMITY_GAIN])) + cg.add(var.set_ambient_gain(config[CONF_AMBIENT_LIGHT_GAIN])) + cg.add(var.set_gesture_led_drive(config[CONF_GESTURE_LED_DRIVE])) + cg.add(var.set_gesture_gain(config[CONF_GESTURE_GAIN])) + cg.add(var.set_gesture_wait_time(config[CONF_GESTURE_WAIT_TIME])) diff --git a/esphome/components/apds9960/apds9960.cpp b/esphome/components/apds9960/apds9960.cpp index 5ba3afbacc..05091f3f7d 100644 --- a/esphome/components/apds9960/apds9960.cpp +++ b/esphome/components/apds9960/apds9960.cpp @@ -46,16 +46,16 @@ void APDS9960::setup() { uint8_t val = 0; APDS9960_ERROR_CHECK(this->read_byte(0x8F, &val)); val &= 0b00111111; - uint8_t led_drive = 0; // led drive, 0 -> 100mA, 1 -> 50mA, 2 -> 25mA, 3 -> 12.5mA - val |= (led_drive & 0b11) << 6; + // led drive, 0 -> 100mA, 1 -> 50mA, 2 -> 25mA, 3 -> 12.5mA + val |= (this->led_drive_ & 0b11) << 6; val &= 0b11110011; - uint8_t proximity_gain = 2; // proximity gain, 0 -> 1x, 1 -> 2X, 2 -> 4X, 4 -> 8X - val |= (proximity_gain & 0b11) << 2; + // proximity gain, 0 -> 1x, 1 -> 2X, 2 -> 4X, 3 -> 8X + val |= (this->proximity_gain_ & 0b11) << 2; val &= 0b11111100; - uint8_t ambient_gain = 1; // ambient light gain, 0 -> 1x, 1 -> 4x, 2 -> 16x, 3 -> 64x - val |= (ambient_gain & 0b11) << 0; + // ambient light gain, 0 -> 1x, 1 -> 4x, 2 -> 16x, 3 -> 64x + val |= (this->ambient_gain_ & 0b11) << 0; APDS9960_WRITE_BYTE(0x8F, val); // Pers (0x8C) -> 0x11 (2 consecutive proximity or ALS for interrupt) @@ -75,19 +75,18 @@ void APDS9960::setup() { // GConf 2 (0xA3, gesture config 2) -> APDS9960_ERROR_CHECK(this->read_byte(0xA3, &val)); val &= 0b10011111; - uint8_t gesture_gain = 2; // gesture gain, 0 -> 1x, 1 -> 2x, 2 -> 4x, 3 -> 8x - val |= (gesture_gain & 0b11) << 5; + // gesture gain, 0 -> 1x, 1 -> 2x, 2 -> 4x, 3 -> 8x + val |= (this->gesture_gain_ & 0b11) << 5; val &= 0b11100111; - uint8_t gesture_led_drive = 0; // gesture led drive, 0 -> 100mA, 1 -> 50mA, 2 -> 25mA, 3 -> 12.5mA - val |= (gesture_led_drive & 0b11) << 3; + // gesture led drive, 0 -> 100mA, 1 -> 50mA, 2 -> 25mA, 3 -> 12.5mA + val |= (this->gesture_led_drive_ & 0b11) << 3; val &= 0b11111000; // gesture wait time // 0 -> 0ms, 1 -> 2.8ms, 2 -> 5.6ms, 3 -> 8.4ms // 4 -> 14.0ms, 5 -> 22.4 ms, 6 -> 30.8ms, 7 -> 39.2 ms - uint8_t gesture_wait_time = 1; // gesture wait time - val |= (gesture_wait_time & 0b111) << 0; + val |= (this->gesture_wait_time_ & 0b111) << 0; APDS9960_WRITE_BYTE(0xA3, val); // GOffsetU (0xA4) -> 0x00 (no offset) diff --git a/esphome/components/apds9960/apds9960.h b/esphome/components/apds9960/apds9960.h index ae44b5da0f..23d9835640 100644 --- a/esphome/components/apds9960/apds9960.h +++ b/esphome/components/apds9960/apds9960.h @@ -16,6 +16,13 @@ class APDS9960 : public PollingComponent, public i2c::I2CDevice { void update() override; void loop() override; + void set_led_drive(uint8_t level) { this->led_drive_ = level; } + void set_proximity_gain(uint8_t gain) { this->proximity_gain_ = gain; } + void set_ambient_gain(uint8_t gain) { this->ambient_gain_ = gain; } + void set_gesture_led_drive(uint8_t level) { this->gesture_led_drive_ = level; } + void set_gesture_gain(uint8_t gain) { this->gesture_gain_ = gain; } + void set_gesture_wait_time(uint8_t wait_time) { this->gesture_wait_time_ = wait_time; } + void set_red_channel(sensor::Sensor *red_channel) { red_channel_ = red_channel; } void set_green_channel(sensor::Sensor *green_channel) { green_channel_ = green_channel; } void set_blue_channel(sensor::Sensor *blue_channel) { blue_channel_ = blue_channel; } @@ -36,6 +43,13 @@ class APDS9960 : public PollingComponent, public i2c::I2CDevice { void report_gesture_(int gesture); void process_dataset_(int up, int down, int left, int right); + uint8_t led_drive_; + uint8_t proximity_gain_; + uint8_t ambient_gain_; + uint8_t gesture_led_drive_; + uint8_t gesture_gain_; + uint8_t gesture_wait_time_; + sensor::Sensor *red_channel_{nullptr}; sensor::Sensor *green_channel_{nullptr}; sensor::Sensor *blue_channel_{nullptr};