Add X9C Potentiometer component (#4183)

fixes https://github.com/esphome/feature-requests/issues/1270
This commit is contained in:
EtienneMD 2023-01-10 20:51:50 -05:00 committed by GitHub
parent a19f0c0db0
commit 1cf3424ebe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 159 additions and 0 deletions

View file

@ -273,6 +273,7 @@ esphome/components/web_server_base/* @OttoWinter
esphome/components/whirlpool/* @glmnet
esphome/components/whynter/* @aeonsablaze
esphome/components/wl_134/* @hobbypunk90
esphome/components/x9c/* @EtienneMD
esphome/components/xiaomi_lywsd03mmc/* @ahpohl
esphome/components/xiaomi_mhoc303/* @drug123
esphome/components/xiaomi_mhoc401/* @vevsvevs

View file

View file

@ -0,0 +1,46 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome import pins
from esphome.components import output
from esphome.const import (
CONF_ID,
CONF_CS_PIN,
CONF_INC_PIN,
CONF_UD_PIN,
CONF_INITIAL_VALUE,
)
CODEOWNERS = ["@EtienneMD"]
x9c_ns = cg.esphome_ns.namespace("x9c")
X9cOutput = x9c_ns.class_("X9cOutput", output.FloatOutput, cg.Component)
CONFIG_SCHEMA = cv.All(
output.FLOAT_OUTPUT_SCHEMA.extend(
{
cv.GenerateID(): cv.declare_id(X9cOutput),
cv.Required(CONF_CS_PIN): pins.internal_gpio_output_pin_schema,
cv.Required(CONF_INC_PIN): pins.internal_gpio_output_pin_schema,
cv.Required(CONF_UD_PIN): pins.internal_gpio_output_pin_schema,
cv.Optional(CONF_INITIAL_VALUE, default=1.0): cv.float_range(
min=0.01, max=1.0
),
}
)
)
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)
await output.register_output(var, config)
cs_pin = await cg.gpio_pin_expression(config[CONF_CS_PIN])
cg.add(var.set_cs_pin(cs_pin))
inc_pin = await cg.gpio_pin_expression(config[CONF_INC_PIN])
cg.add(var.set_inc_pin(inc_pin))
ud_pin = await cg.gpio_pin_expression(config[CONF_UD_PIN])
cg.add(var.set_ud_pin(ud_pin))
cg.add(var.set_initial_value(config[CONF_INITIAL_VALUE]))

View file

@ -0,0 +1,72 @@
#include "x9c.h"
#include "esphome/core/log.h"
namespace esphome {
namespace x9c {
static const char *const TAG = "x9c.output";
void X9cOutput::trim_value(int change_amount) {
if (change_amount > 0) { // Set change direction
this->ud_pin_->digital_write(true);
} else {
this->ud_pin_->digital_write(false);
}
this->inc_pin_->digital_write(true);
this->cs_pin_->digital_write(false); // Select chip
for (int i = 0; i < abs(change_amount); i++) { // Move wiper
this->inc_pin_->digital_write(true);
delayMicroseconds(1);
this->inc_pin_->digital_write(false);
delayMicroseconds(1);
}
delayMicroseconds(100); // Let value settle
this->inc_pin_->digital_write(false);
this->cs_pin_->digital_write(true); // Deselect chip safely (no save)
}
void X9cOutput::setup() {
ESP_LOGCONFIG(TAG, "Setting up X9C Potentiometer with initial value of %f", this->initial_value_);
this->inc_pin_->get_pin();
this->inc_pin_->setup();
this->inc_pin_->digital_write(false);
this->cs_pin_->get_pin();
this->cs_pin_->setup();
this->cs_pin_->digital_write(true);
this->ud_pin_->get_pin();
this->ud_pin_->setup();
if (this->initial_value_ <= 0.50) {
this->trim_value(-101); // Set min value (beyond 0)
this->trim_value((int) (this->initial_value_ * 100));
} else {
this->trim_value(101); // Set max value (beyond 100)
this->trim_value((int) (this->initial_value_ * 100) - 100);
}
this->pot_value_ = this->initial_value_;
this->write_state(this->initial_value_);
}
void X9cOutput::write_state(float state) {
this->trim_value((int) ((state - this->pot_value_) * 100));
this->pot_value_ = state;
}
void X9cOutput::dump_config() {
ESP_LOGCONFIG(TAG, "X9C Potentiometer Output:");
LOG_PIN(" Chip Select Pin: ", this->cs_pin_);
LOG_PIN(" Increment Pin: ", this->inc_pin_);
LOG_PIN(" Up/Down Pin: ", this->ud_pin_);
ESP_LOGCONFIG(TAG, " Initial Value: %f", this->initial_value_);
LOG_FLOAT_OUTPUT(this);
}
} // namespace x9c
} // namespace esphome

View file

@ -0,0 +1,32 @@
#pragma once
#include "esphome/core/component.h"
#include "esphome/core/hal.h"
#include "esphome/components/output/float_output.h"
namespace esphome {
namespace x9c {
class X9cOutput : public output::FloatOutput, public Component {
public:
void set_cs_pin(InternalGPIOPin *pin) { cs_pin_ = pin; }
void set_inc_pin(InternalGPIOPin *pin) { inc_pin_ = pin; }
void set_ud_pin(InternalGPIOPin *pin) { ud_pin_ = pin; }
void set_initial_value(float initial_value) { initial_value_ = initial_value; }
void setup() override;
void dump_config() override;
void trim_value(int change_amount);
protected:
void write_state(float state) override;
InternalGPIOPin *cs_pin_;
InternalGPIOPin *inc_pin_;
InternalGPIOPin *ud_pin_;
float initial_value_;
float pot_value_;
};
} // namespace x9c
} // namespace esphome

View file

@ -307,6 +307,7 @@ CONF_ILLUMINANCE = "illuminance"
CONF_IMPEDANCE = "impedance"
CONF_IMPORT_ACTIVE_ENERGY = "import_active_energy"
CONF_IMPORT_REACTIVE_ENERGY = "import_reactive_energy"
CONF_INC_PIN = "inc_pin"
CONF_INCLUDE_INTERNAL = "include_internal"
CONF_INCLUDES = "includes"
CONF_INDEX = "index"
@ -742,6 +743,7 @@ CONF_TX_POWER = "tx_power"
CONF_TYPE = "type"
CONF_TYPE_ID = "type_id"
CONF_UART_ID = "uart_id"
CONF_UD_PIN = "ud_pin"
CONF_UID = "uid"
CONF_UNIQUE = "unique"
CONF_UNIT_OF_MEASUREMENT = "unit_of_measurement"

View file

@ -1713,6 +1713,12 @@ output:
id: bp5758d_warmwhite
channel: 4
current: 10
- platform: x9c
id: test_x9c
cs_pin: GPIO25
inc_pin: GPIO26
ud_pin: GPIO27
initial_value: 0.5
e131: