mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 15:12:06 +00:00 
			
		
		
		
	mpr121: Add GPIO support (#6776)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
		| @@ -1,19 +1,32 @@ | ||||
| import esphome.codegen as cg | ||||
| import esphome.config_validation as cv | ||||
| import esphome.final_validate as fv | ||||
| from esphome import pins | ||||
| from esphome.components import i2c | ||||
| from esphome.const import CONF_ID | ||||
| from esphome.const import ( | ||||
|     CONF_BINARY_SENSOR, | ||||
|     CONF_CHANNEL, | ||||
|     CONF_ID, | ||||
|     CONF_INPUT, | ||||
|     CONF_INVERTED, | ||||
|     CONF_MODE, | ||||
|     CONF_NUMBER, | ||||
|     CONF_OUTPUT, | ||||
| ) | ||||
|  | ||||
| CONF_TOUCH_THRESHOLD = "touch_threshold" | ||||
| CONF_RELEASE_THRESHOLD = "release_threshold" | ||||
| CONF_TOUCH_DEBOUNCE = "touch_debounce" | ||||
| CONF_RELEASE_DEBOUNCE = "release_debounce" | ||||
| CONF_MAX_TOUCH_CHANNEL = "max_touch_channel" | ||||
| CONF_MPR121 = "mpr121" | ||||
| CONF_MPR121_ID = "mpr121_id" | ||||
|  | ||||
| DEPENDENCIES = ["i2c"] | ||||
| AUTO_LOAD = ["binary_sensor"] | ||||
|  | ||||
| mpr121_ns = cg.esphome_ns.namespace("mpr121") | ||||
| CONF_MPR121_ID = "mpr121_id" | ||||
| MPR121Component = mpr121_ns.class_("MPR121Component", cg.Component, i2c.I2CDevice) | ||||
| MPR121GPIOPin = mpr121_ns.class_("MPR121GPIOPin", cg.GPIOPin) | ||||
|  | ||||
| MULTI_CONF = True | ||||
| CONFIG_SCHEMA = ( | ||||
| @@ -28,6 +41,7 @@ CONFIG_SCHEMA = ( | ||||
|             cv.Optional(CONF_RELEASE_THRESHOLD, default=0x06): cv.int_range( | ||||
|                 min=0x05, max=0x30 | ||||
|             ), | ||||
|             cv.Optional(CONF_MAX_TOUCH_CHANNEL): cv.int_range(min=3, max=11), | ||||
|         } | ||||
|     ) | ||||
|     .extend(cv.COMPONENT_SCHEMA) | ||||
| @@ -35,11 +49,79 @@ CONFIG_SCHEMA = ( | ||||
| ) | ||||
|  | ||||
|  | ||||
| def _final_validate(config): | ||||
|     fconf = fv.full_config.get() | ||||
|     max_touch_channel = 3 | ||||
|     if (binary_sensors := fconf.get(CONF_BINARY_SENSOR)) is not None: | ||||
|         for binary_sensor in binary_sensors: | ||||
|             if binary_sensor.get(CONF_MPR121_ID) == config[CONF_ID]: | ||||
|                 max_touch_channel = max(max_touch_channel, binary_sensor[CONF_CHANNEL]) | ||||
|     if max_touch_channel_in_config := config.get(CONF_MAX_TOUCH_CHANNEL): | ||||
|         if max_touch_channel != max_touch_channel_in_config: | ||||
|             raise cv.Invalid( | ||||
|                 "Max touch channel must equal the highest binary sensor channel or be removed for auto calculation", | ||||
|                 path=[CONF_MAX_TOUCH_CHANNEL], | ||||
|             ) | ||||
|     path = fconf.get_path_for_id(config[CONF_ID])[:-1] | ||||
|     this_config = fconf.get_config_for_path(path) | ||||
|     this_config[CONF_MAX_TOUCH_CHANNEL] = max_touch_channel | ||||
|  | ||||
|  | ||||
| FINAL_VALIDATE_SCHEMA = _final_validate | ||||
|  | ||||
|  | ||||
| async def to_code(config): | ||||
|     var = cg.new_Pvariable(config[CONF_ID]) | ||||
|     cg.add(var.set_touch_debounce(config[CONF_TOUCH_DEBOUNCE])) | ||||
|     cg.add(var.set_release_debounce(config[CONF_RELEASE_DEBOUNCE])) | ||||
|     cg.add(var.set_touch_threshold(config[CONF_TOUCH_THRESHOLD])) | ||||
|     cg.add(var.set_release_threshold(config[CONF_RELEASE_THRESHOLD])) | ||||
|     cg.add(var.set_max_touch_channel(config[CONF_MAX_TOUCH_CHANNEL])) | ||||
|     await cg.register_component(var, config) | ||||
|     await i2c.register_i2c_device(var, config) | ||||
|  | ||||
|  | ||||
| def validate_mode(value): | ||||
|     if bool(value[CONF_INPUT]) == bool(value[CONF_OUTPUT]): | ||||
|         raise cv.Invalid("Mode must be either input or output") | ||||
|     return value | ||||
|  | ||||
|  | ||||
| # https://www.nxp.com/docs/en/data-sheet/MPR121.pdf, page 4 | ||||
| # | ||||
| # Among the 12 electrode inputs, 8 inputs are designed as multifunctional pins. When these pins are | ||||
| # not configured as electrodes, they may be used to drive LEDs or used for general purpose input or | ||||
| # output. | ||||
| MPR121_GPIO_PIN_SCHEMA = pins.gpio_base_schema( | ||||
|     MPR121GPIOPin, | ||||
|     cv.int_range(min=4, max=11), | ||||
|     modes=[CONF_INPUT, CONF_OUTPUT], | ||||
|     mode_validator=validate_mode, | ||||
| ).extend( | ||||
|     { | ||||
|         cv.Required(CONF_MPR121): cv.use_id(MPR121Component), | ||||
|     } | ||||
| ) | ||||
|  | ||||
|  | ||||
| def mpr121_pin_final_validate(pin_config, parent_config): | ||||
|     if pin_config[CONF_NUMBER] <= parent_config[CONF_MAX_TOUCH_CHANNEL]: | ||||
|         raise cv.Invalid( | ||||
|             "Pin number must be higher than the max touch channel of the MPR121 component", | ||||
|         ) | ||||
|  | ||||
|  | ||||
| @pins.PIN_SCHEMA_REGISTRY.register( | ||||
|     CONF_MPR121, MPR121_GPIO_PIN_SCHEMA, mpr121_pin_final_validate | ||||
| ) | ||||
| async def mpr121_gpio_pin_to_code(config): | ||||
|     var = cg.new_Pvariable(config[CONF_ID]) | ||||
|     parent = await cg.get_variable(config[CONF_MPR121]) | ||||
|  | ||||
|     cg.add(var.set_parent(parent)) | ||||
|  | ||||
|     num = config[CONF_NUMBER] | ||||
|     cg.add(var.set_pin(num)) | ||||
|     cg.add(var.set_inverted(config[CONF_INVERTED])) | ||||
|     cg.add(var.set_flags(pins.gpio_flags_expr(config[CONF_MODE]))) | ||||
|     return var | ||||
|   | ||||
| @@ -2,7 +2,7 @@ import esphome.codegen as cg | ||||
| import esphome.config_validation as cv | ||||
| from esphome.components import binary_sensor | ||||
| from esphome.const import CONF_CHANNEL | ||||
| from . import ( | ||||
| from .. import ( | ||||
|     mpr121_ns, | ||||
|     MPR121Component, | ||||
|     CONF_MPR121_ID, | ||||
| @@ -11,9 +11,9 @@ from . import ( | ||||
| ) | ||||
| 
 | ||||
| DEPENDENCIES = ["mpr121"] | ||||
| MPR121Channel = mpr121_ns.class_("MPR121Channel", binary_sensor.BinarySensor) | ||||
| MPR121BinarySensor = mpr121_ns.class_("MPR121BinarySensor", binary_sensor.BinarySensor) | ||||
| 
 | ||||
| CONFIG_SCHEMA = binary_sensor.binary_sensor_schema(MPR121Channel).extend( | ||||
| CONFIG_SCHEMA = binary_sensor.binary_sensor_schema(MPR121BinarySensor).extend( | ||||
|     { | ||||
|         cv.GenerateID(CONF_MPR121_ID): cv.use_id(MPR121Component), | ||||
|         cv.Required(CONF_CHANNEL): cv.int_range(min=0, max=11), | ||||
| @@ -27,6 +27,7 @@ async def to_code(config): | ||||
|     var = await binary_sensor.new_binary_sensor(config) | ||||
|     hub = await cg.get_variable(config[CONF_MPR121_ID]) | ||||
|     cg.add(var.set_channel(config[CONF_CHANNEL])) | ||||
|     cg.register_parented(var, hub) | ||||
| 
 | ||||
|     if CONF_TOUCH_THRESHOLD in config: | ||||
|         cg.add(var.set_touch_threshold(config[CONF_TOUCH_THRESHOLD])) | ||||
| @@ -0,0 +1,20 @@ | ||||
| #include "mpr121_binary_sensor.h" | ||||
|  | ||||
| namespace esphome { | ||||
| namespace mpr121 { | ||||
|  | ||||
| void MPR121BinarySensor::setup() { | ||||
|   uint8_t touch_threshold = this->touch_threshold_.value_or(this->parent_->get_touch_threshold()); | ||||
|   this->parent_->write_byte(MPR121_TOUCHTH_0 + 2 * this->channel_, touch_threshold); | ||||
|  | ||||
|   uint8_t release_threshold = this->release_threshold_.value_or(this->parent_->get_release_threshold()); | ||||
|   this->parent_->write_byte(MPR121_RELEASETH_0 + 2 * this->channel_, release_threshold); | ||||
| } | ||||
|  | ||||
| void MPR121BinarySensor::process(uint16_t data) { | ||||
|   bool new_state = data & (1 << this->channel_); | ||||
|   this->publish_state(new_state); | ||||
| } | ||||
|  | ||||
| }  // namespace mpr121 | ||||
| }  // namespace esphome | ||||
| @@ -0,0 +1,26 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include "esphome/components/binary_sensor/binary_sensor.h" | ||||
|  | ||||
| #include "../mpr121.h" | ||||
|  | ||||
| namespace esphome { | ||||
| namespace mpr121 { | ||||
|  | ||||
| class MPR121BinarySensor : public binary_sensor::BinarySensor, public MPR121Channel, public Parented<MPR121Component> { | ||||
|  public: | ||||
|   void set_channel(uint8_t channel) { this->channel_ = channel; } | ||||
|   void set_touch_threshold(uint8_t touch_threshold) { this->touch_threshold_ = touch_threshold; }; | ||||
|   void set_release_threshold(uint8_t release_threshold) { this->release_threshold_ = release_threshold; }; | ||||
|  | ||||
|   void setup() override; | ||||
|   void process(uint16_t data) override; | ||||
|  | ||||
|  protected: | ||||
|   uint8_t channel_{0}; | ||||
|   optional<uint8_t> touch_threshold_{}; | ||||
|   optional<uint8_t> release_threshold_{}; | ||||
| }; | ||||
|  | ||||
| }  // namespace mpr121 | ||||
| }  // namespace esphome | ||||
| @@ -1,6 +1,9 @@ | ||||
| #include "mpr121.h" | ||||
| #include "esphome/core/log.h" | ||||
|  | ||||
| #include <cstdint> | ||||
|  | ||||
| #include "esphome/core/hal.h" | ||||
| #include "esphome/core/log.h" | ||||
|  | ||||
| namespace esphome { | ||||
| namespace mpr121 { | ||||
| @@ -20,10 +23,7 @@ void MPR121Component::setup() { | ||||
|  | ||||
|   // set touch sensitivity for all 12 channels | ||||
|   for (auto *channel : this->channels_) { | ||||
|     this->write_byte(MPR121_TOUCHTH_0 + 2 * channel->channel_, | ||||
|                      channel->touch_threshold_.value_or(this->touch_threshold_)); | ||||
|     this->write_byte(MPR121_RELEASETH_0 + 2 * channel->channel_, | ||||
|                      channel->release_threshold_.value_or(this->release_threshold_)); | ||||
|     channel->setup(); | ||||
|   } | ||||
|   this->write_byte(MPR121_MHDR, 0x01); | ||||
|   this->write_byte(MPR121_NHDR, 0x01); | ||||
| @@ -44,8 +44,15 @@ void MPR121Component::setup() { | ||||
|   this->write_byte(MPR121_CONFIG1, 0x10); | ||||
|   // 0.5uS encoding, 1ms period | ||||
|   this->write_byte(MPR121_CONFIG2, 0x20); | ||||
|   // start with first 5 bits of baseline tracking | ||||
|   this->write_byte(MPR121_ECR, 0x8F); | ||||
|  | ||||
|   // Write the Electrode Configuration Register | ||||
|   // * Highest 2 bits is "Calibration Lock", which we set to a value corresponding to 5 bits. | ||||
|   // * The 2 bits below is "Proximity Enable" and are left at 0. | ||||
|   // * The 4 least significant bits control how many electrodes are enabled. Electrodes are enabled | ||||
|   //   as a range, starting at 0 up to the highest channel index used. | ||||
|   this->write_byte(MPR121_ECR, 0x80 | (this->max_touch_channel_ + 1)); | ||||
|  | ||||
|   this->flush_gpio_(); | ||||
| } | ||||
|  | ||||
| void MPR121Component::set_touch_debounce(uint8_t debounce) { | ||||
| @@ -86,6 +93,72 @@ void MPR121Component::loop() { | ||||
|  | ||||
|   for (auto *channel : this->channels_) | ||||
|     channel->process(val); | ||||
|  | ||||
|   this->read_byte(MPR121_GPIODATA, &this->gpio_input_); | ||||
| } | ||||
|  | ||||
| bool MPR121Component::digital_read(uint8_t ionum) { return (this->gpio_input_ & (1 << ionum)) != 0; } | ||||
|  | ||||
| void MPR121Component::digital_write(uint8_t ionum, bool value) { | ||||
|   if (value) { | ||||
|     this->gpio_output_ |= (1 << ionum); | ||||
|   } else { | ||||
|     this->gpio_output_ &= ~(1 << ionum); | ||||
|   } | ||||
|   this->flush_gpio_(); | ||||
| } | ||||
|  | ||||
| void MPR121Component::pin_mode(uint8_t ionum, gpio::Flags flags) { | ||||
|   this->gpio_enable_ |= (1 << ionum); | ||||
|   if (flags & gpio::FLAG_INPUT) { | ||||
|     this->gpio_direction_ &= ~(1 << ionum); | ||||
|   } else if (flags & gpio::FLAG_OUTPUT) { | ||||
|     this->gpio_direction_ |= 1 << ionum; | ||||
|   } | ||||
|   this->flush_gpio_(); | ||||
| } | ||||
|  | ||||
| bool MPR121Component::flush_gpio_() { | ||||
|   if (this->is_failed()) { | ||||
|     return false; | ||||
|   } | ||||
|  | ||||
|   // TODO: The CTL registers can configure internal pullup/pulldown resistors. | ||||
|   this->write_byte(MPR121_GPIOCTL0, 0x00); | ||||
|   this->write_byte(MPR121_GPIOCTL1, 0x00); | ||||
|   this->write_byte(MPR121_GPIOEN, this->gpio_enable_); | ||||
|   this->write_byte(MPR121_GPIODIR, this->gpio_direction_); | ||||
|  | ||||
|   if (!this->write_byte(MPR121_GPIODATA, this->gpio_output_)) { | ||||
|     this->status_set_warning(); | ||||
|     return false; | ||||
|   } | ||||
|  | ||||
|   this->status_clear_warning(); | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| void MPR121GPIOPin::setup() { this->pin_mode(this->flags_); } | ||||
|  | ||||
| void MPR121GPIOPin::pin_mode(gpio::Flags flags) { | ||||
|   assert(this->pin_ >= 4); | ||||
|   this->parent_->pin_mode(this->pin_ - 4, flags); | ||||
| } | ||||
|  | ||||
| bool MPR121GPIOPin::digital_read() { | ||||
|   assert(this->pin_ >= 4); | ||||
|   return this->parent_->digital_read(this->pin_ - 4) != this->inverted_; | ||||
| } | ||||
|  | ||||
| void MPR121GPIOPin::digital_write(bool value) { | ||||
|   assert(this->pin_ >= 4); | ||||
|   this->parent_->digital_write(this->pin_ - 4, value != this->inverted_); | ||||
| } | ||||
|  | ||||
| std::string MPR121GPIOPin::dump_summary() const { | ||||
|   char buffer[32]; | ||||
|   snprintf(buffer, sizeof(buffer), "ELE%u on MPR121", this->pin_); | ||||
|   return buffer; | ||||
| } | ||||
|  | ||||
| }  // namespace mpr121 | ||||
|   | ||||
| @@ -1,8 +1,10 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include "esphome/core/component.h" | ||||
| #include "esphome/core/defines.h" | ||||
| #include "esphome/core/hal.h" | ||||
|  | ||||
| #include "esphome/components/i2c/i2c.h" | ||||
| #include "esphome/components/binary_sensor/binary_sensor.h" | ||||
|  | ||||
| #include <vector> | ||||
|  | ||||
| @@ -39,6 +41,9 @@ enum { | ||||
|   MPR121_UPLIMIT = 0x7D, | ||||
|   MPR121_LOWLIMIT = 0x7E, | ||||
|   MPR121_TARGETLIMIT = 0x7F, | ||||
|   MPR121_GPIOCTL0 = 0x73, | ||||
|   MPR121_GPIOCTL1 = 0x74, | ||||
|   MPR121_GPIODATA = 0x75, | ||||
|   MPR121_GPIODIR = 0x76, | ||||
|   MPR121_GPIOEN = 0x77, | ||||
|   MPR121_GPIOSET = 0x78, | ||||
| @@ -47,19 +52,10 @@ enum { | ||||
|   MPR121_SOFTRESET = 0x80, | ||||
| }; | ||||
|  | ||||
| class MPR121Channel : public binary_sensor::BinarySensor { | ||||
|   friend class MPR121Component; | ||||
|  | ||||
| class MPR121Channel { | ||||
|  public: | ||||
|   void set_channel(uint8_t channel) { channel_ = channel; } | ||||
|   void process(uint16_t data) { this->publish_state(static_cast<bool>(data & (1 << this->channel_))); } | ||||
|   void set_touch_threshold(uint8_t touch_threshold) { this->touch_threshold_ = touch_threshold; }; | ||||
|   void set_release_threshold(uint8_t release_threshold) { this->release_threshold_ = release_threshold; }; | ||||
|  | ||||
|  protected: | ||||
|   uint8_t channel_{0}; | ||||
|   optional<uint8_t> touch_threshold_{}; | ||||
|   optional<uint8_t> release_threshold_{}; | ||||
|   virtual void setup() = 0; | ||||
|   virtual void process(uint16_t data) = 0; | ||||
| }; | ||||
|  | ||||
| class MPR121Component : public Component, public i2c::I2CDevice { | ||||
| @@ -69,23 +65,63 @@ class MPR121Component : public Component, public i2c::I2CDevice { | ||||
|   void set_release_debounce(uint8_t debounce); | ||||
|   void set_touch_threshold(uint8_t touch_threshold) { this->touch_threshold_ = touch_threshold; }; | ||||
|   void set_release_threshold(uint8_t release_threshold) { this->release_threshold_ = release_threshold; }; | ||||
|   uint8_t get_touch_threshold() { return this->touch_threshold_; }; | ||||
|   uint8_t get_release_threshold() { return this->release_threshold_; }; | ||||
|   uint8_t get_touch_threshold() const { return this->touch_threshold_; }; | ||||
|   uint8_t get_release_threshold() const { return this->release_threshold_; }; | ||||
|   void setup() override; | ||||
|   void dump_config() override; | ||||
|   float get_setup_priority() const override { return setup_priority::DATA; } | ||||
|   float get_setup_priority() const override { return setup_priority::IO; } | ||||
|   void loop() override; | ||||
|  | ||||
|   void set_max_touch_channel(uint8_t max_touch_channel) { this->max_touch_channel_ = max_touch_channel; } | ||||
|  | ||||
|   // GPIO helper functions. | ||||
|   bool digital_read(uint8_t ionum); | ||||
|   void digital_write(uint8_t ionum, bool value); | ||||
|   void pin_mode(uint8_t ionum, gpio::Flags flags); | ||||
|  | ||||
|  protected: | ||||
|   std::vector<MPR121Channel *> channels_{}; | ||||
|   uint8_t debounce_{0}; | ||||
|   uint8_t touch_threshold_{}; | ||||
|   uint8_t release_threshold_{}; | ||||
|   uint8_t max_touch_channel_{3}; | ||||
|   enum ErrorCode { | ||||
|     NONE = 0, | ||||
|     COMMUNICATION_FAILED, | ||||
|     WRONG_CHIP_STATE, | ||||
|   } error_code_{NONE}; | ||||
|  | ||||
|   bool flush_gpio_(); | ||||
|  | ||||
|   /// The enable mask - zero means high Z, 1 means GPIO usage | ||||
|   uint8_t gpio_enable_{0x00}; | ||||
|   /// Mask for the pin mode - 1 means output, 0 means input | ||||
|   uint8_t gpio_direction_{0x00}; | ||||
|   /// The mask to write as output state - 1 means HIGH, 0 means LOW | ||||
|   uint8_t gpio_output_{0x00}; | ||||
|   /// The mask to read as input state - 1 means HIGH, 0 means LOW | ||||
|   uint8_t gpio_input_{0x00}; | ||||
| }; | ||||
|  | ||||
| /// Helper class to expose a MPR121 pin as an internal input GPIO pin. | ||||
| class MPR121GPIOPin : public GPIOPin { | ||||
|  public: | ||||
|   void setup() override; | ||||
|   void pin_mode(gpio::Flags flags) override; | ||||
|   bool digital_read() override; | ||||
|   void digital_write(bool value) override; | ||||
|   std::string dump_summary() const override; | ||||
|  | ||||
|   void set_parent(MPR121Component *parent) { this->parent_ = parent; } | ||||
|   void set_pin(uint8_t pin) { this->pin_ = pin; } | ||||
|   void set_inverted(bool inverted) { this->inverted_ = inverted; } | ||||
|   void set_flags(gpio::Flags flags) { this->flags_ = flags; } | ||||
|  | ||||
|  protected: | ||||
|   MPR121Component *parent_; | ||||
|   uint8_t pin_; | ||||
|   bool inverted_; | ||||
|   gpio::Flags flags_; | ||||
| }; | ||||
|  | ||||
| }  // namespace mpr121 | ||||
|   | ||||
							
								
								
									
										41
									
								
								tests/components/mpr121/common.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								tests/components/mpr121/common.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | ||||
| i2c: | ||||
|   - id: i2c_mpr121 | ||||
|     scl: ${i2c_scl} | ||||
|     sda: ${i2c_sda} | ||||
|  | ||||
| mpr121: | ||||
|   id: mpr121_first | ||||
|   address: 0x5A | ||||
|  | ||||
| binary_sensor: | ||||
|   - platform: mpr121 | ||||
|     id: touchkey0 | ||||
|     name: touchkey0 | ||||
|     channel: 0 | ||||
|   - platform: mpr121 | ||||
|     id: bin1 | ||||
|     name: touchkey1 | ||||
|     channel: 1 | ||||
|   - platform: mpr121 | ||||
|     id: bin2 | ||||
|     name: touchkey2 | ||||
|     channel: 2 | ||||
|   - platform: mpr121 | ||||
|     id: bin3 | ||||
|     name: touchkey3 | ||||
|     channel: 6 | ||||
|  | ||||
| output: | ||||
|   - platform: gpio | ||||
|     id: gpio1 | ||||
|     pin: | ||||
|       mpr121: mpr121_first | ||||
|       number: 7 | ||||
|       mode: OUTPUT | ||||
|   - platform: gpio | ||||
|     id: gpio2 | ||||
|     pin: | ||||
|       mpr121: mpr121_first | ||||
|       number: 11 | ||||
|       mode: OUTPUT | ||||
|       inverted: true | ||||
| @@ -1,26 +1,5 @@ | ||||
| i2c: | ||||
|   - id: i2c_mpr121 | ||||
|     scl: 5 | ||||
|     sda: 4 | ||||
| substitutions: | ||||
|   i2c_scl: GPIO5 | ||||
|   i2c_sda: GPIO4 | ||||
|  | ||||
| mpr121: | ||||
|   id: mpr121_first | ||||
|   address: 0x5A | ||||
|  | ||||
| binary_sensor: | ||||
|   - platform: mpr121 | ||||
|     id: touchkey0 | ||||
|     name: touchkey0 | ||||
|     channel: 0 | ||||
|   - platform: mpr121 | ||||
|     id: bin1 | ||||
|     name: touchkey1 | ||||
|     channel: 1 | ||||
|   - platform: mpr121 | ||||
|     id: bin2 | ||||
|     name: touchkey2 | ||||
|     channel: 2 | ||||
|   - platform: mpr121 | ||||
|     id: bin3 | ||||
|     name: touchkey3 | ||||
|     channel: 3 | ||||
| <<: !include common.yaml | ||||
|   | ||||
| @@ -1,26 +1,5 @@ | ||||
| i2c: | ||||
|   - id: i2c_mpr121 | ||||
|     scl: 5 | ||||
|     sda: 4 | ||||
| substitutions: | ||||
|   i2c_scl: GPIO5 | ||||
|   i2c_sda: GPIO4 | ||||
|  | ||||
| mpr121: | ||||
|   id: mpr121_first | ||||
|   address: 0x5A | ||||
|  | ||||
| binary_sensor: | ||||
|   - platform: mpr121 | ||||
|     id: touchkey0 | ||||
|     name: touchkey0 | ||||
|     channel: 0 | ||||
|   - platform: mpr121 | ||||
|     id: bin1 | ||||
|     name: touchkey1 | ||||
|     channel: 1 | ||||
|   - platform: mpr121 | ||||
|     id: bin2 | ||||
|     name: touchkey2 | ||||
|     channel: 2 | ||||
|   - platform: mpr121 | ||||
|     id: bin3 | ||||
|     name: touchkey3 | ||||
|     channel: 3 | ||||
| <<: !include common.yaml | ||||
|   | ||||
| @@ -1,26 +1,5 @@ | ||||
| i2c: | ||||
|   - id: i2c_mpr121 | ||||
|     scl: 16 | ||||
|     sda: 17 | ||||
| substitutions: | ||||
|   i2c_scl: GPIO16 | ||||
|   i2c_sda: GPIO17 | ||||
|  | ||||
| mpr121: | ||||
|   id: mpr121_first | ||||
|   address: 0x5A | ||||
|  | ||||
| binary_sensor: | ||||
|   - platform: mpr121 | ||||
|     id: touchkey0 | ||||
|     name: touchkey0 | ||||
|     channel: 0 | ||||
|   - platform: mpr121 | ||||
|     id: bin1 | ||||
|     name: touchkey1 | ||||
|     channel: 1 | ||||
|   - platform: mpr121 | ||||
|     id: bin2 | ||||
|     name: touchkey2 | ||||
|     channel: 2 | ||||
|   - platform: mpr121 | ||||
|     id: bin3 | ||||
|     name: touchkey3 | ||||
|     channel: 3 | ||||
| <<: !include common.yaml | ||||
|   | ||||
| @@ -1,26 +1,5 @@ | ||||
| i2c: | ||||
|   - id: i2c_mpr121 | ||||
|     scl: 16 | ||||
|     sda: 17 | ||||
| substitutions: | ||||
|   i2c_scl: GPIO16 | ||||
|   i2c_sda: GPIO17 | ||||
|  | ||||
| mpr121: | ||||
|   id: mpr121_first | ||||
|   address: 0x5A | ||||
|  | ||||
| binary_sensor: | ||||
|   - platform: mpr121 | ||||
|     id: touchkey0 | ||||
|     name: touchkey0 | ||||
|     channel: 0 | ||||
|   - platform: mpr121 | ||||
|     id: bin1 | ||||
|     name: touchkey1 | ||||
|     channel: 1 | ||||
|   - platform: mpr121 | ||||
|     id: bin2 | ||||
|     name: touchkey2 | ||||
|     channel: 2 | ||||
|   - platform: mpr121 | ||||
|     id: bin3 | ||||
|     name: touchkey3 | ||||
|     channel: 3 | ||||
| <<: !include common.yaml | ||||
|   | ||||
| @@ -1,26 +1,5 @@ | ||||
| i2c: | ||||
|   - id: i2c_mpr121 | ||||
|     scl: 5 | ||||
|     sda: 4 | ||||
| substitutions: | ||||
|   i2c_scl: GPIO5 | ||||
|   i2c_sda: GPIO4 | ||||
|  | ||||
| mpr121: | ||||
|   id: mpr121_first | ||||
|   address: 0x5A | ||||
|  | ||||
| binary_sensor: | ||||
|   - platform: mpr121 | ||||
|     id: touchkey0 | ||||
|     name: touchkey0 | ||||
|     channel: 0 | ||||
|   - platform: mpr121 | ||||
|     id: bin1 | ||||
|     name: touchkey1 | ||||
|     channel: 1 | ||||
|   - platform: mpr121 | ||||
|     id: bin2 | ||||
|     name: touchkey2 | ||||
|     channel: 2 | ||||
|   - platform: mpr121 | ||||
|     id: bin3 | ||||
|     name: touchkey3 | ||||
|     channel: 3 | ||||
| <<: !include common.yaml | ||||
|   | ||||
| @@ -1,26 +1,5 @@ | ||||
| i2c: | ||||
|   - id: i2c_mpr121 | ||||
|     scl: 5 | ||||
|     sda: 4 | ||||
| substitutions: | ||||
|   i2c_scl: GPIO5 | ||||
|   i2c_sda: GPIO4 | ||||
|  | ||||
| mpr121: | ||||
|   id: mpr121_first | ||||
|   address: 0x5A | ||||
|  | ||||
| binary_sensor: | ||||
|   - platform: mpr121 | ||||
|     id: touchkey0 | ||||
|     name: touchkey0 | ||||
|     channel: 0 | ||||
|   - platform: mpr121 | ||||
|     id: bin1 | ||||
|     name: touchkey1 | ||||
|     channel: 1 | ||||
|   - platform: mpr121 | ||||
|     id: bin2 | ||||
|     name: touchkey2 | ||||
|     channel: 2 | ||||
|   - platform: mpr121 | ||||
|     id: bin3 | ||||
|     name: touchkey3 | ||||
|     channel: 3 | ||||
| <<: !include common.yaml | ||||
|   | ||||
| @@ -344,10 +344,6 @@ apds9960: | ||||
|   address: 0x20 | ||||
|   update_interval: 60s | ||||
|  | ||||
| mpr121: | ||||
|   id: mpr121_first | ||||
|   address: 0x5A | ||||
|  | ||||
| binary_sensor: | ||||
|   - platform: apds9960 | ||||
|     direction: up | ||||
| @@ -371,25 +367,6 @@ binary_sensor: | ||||
|     direction: right | ||||
|     name: APDS9960 Right | ||||
|  | ||||
|   - platform: mpr121 | ||||
|     id: touchkey0 | ||||
|     channel: 0 | ||||
|     name: touchkey0 | ||||
|   - platform: mpr121 | ||||
|     channel: 1 | ||||
|     name: touchkey1 | ||||
|     id: bin1 | ||||
|   - platform: mpr121 | ||||
|     channel: 2 | ||||
|     name: touchkey2 | ||||
|     id: bin2 | ||||
|   - platform: mpr121 | ||||
|     channel: 3 | ||||
|     name: touchkey3 | ||||
|     id: bin3 | ||||
|     on_press: | ||||
|       then: | ||||
|         - switch.toggle: mpr121_toggle | ||||
|   - platform: ttp229_lsf | ||||
|     channel: 1 | ||||
|     name: TTP229 LSF Test | ||||
| @@ -443,10 +420,6 @@ grove_tb6612fng: | ||||
|   address: 0x14 | ||||
|  | ||||
| switch: | ||||
|   - platform: template | ||||
|     name: mpr121_toggle | ||||
|     id: mpr121_toggle | ||||
|     optimistic: true | ||||
|   - platform: gpio | ||||
|     id: gpio_switch1 | ||||
|     pin: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user