mirror of
https://github.com/esphome/esphome.git
synced 2024-11-29 18:24:13 +01:00
Add restore_mode to rotary_encoder (#2643)
This commit is contained in:
parent
5ea77894b7
commit
379c3e98f5
3 changed files with 63 additions and 0 deletions
|
@ -125,6 +125,22 @@ void IRAM_ATTR HOT RotaryEncoderSensorStore::gpio_intr(RotaryEncoderSensorStore
|
||||||
|
|
||||||
void RotaryEncoderSensor::setup() {
|
void RotaryEncoderSensor::setup() {
|
||||||
ESP_LOGCONFIG(TAG, "Setting up Rotary Encoder '%s'...", this->name_.c_str());
|
ESP_LOGCONFIG(TAG, "Setting up Rotary Encoder '%s'...", this->name_.c_str());
|
||||||
|
|
||||||
|
int32_t initial_value = 0;
|
||||||
|
switch (this->restore_mode_) {
|
||||||
|
case ROTARY_ENCODER_RESTORE_DEFAULT_ZERO:
|
||||||
|
this->rtc_ = global_preferences->make_preference<int32_t>(this->get_object_id_hash());
|
||||||
|
if (!this->rtc_.load(&initial_value)) {
|
||||||
|
initial_value = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ROTARY_ENCODER_ALWAYS_ZERO:
|
||||||
|
initial_value = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this->store_.counter = initial_value;
|
||||||
|
this->store_.last_read = initial_value;
|
||||||
|
|
||||||
this->pin_a_->setup();
|
this->pin_a_->setup();
|
||||||
this->store_.pin_a = this->pin_a_->to_isr();
|
this->store_.pin_a = this->pin_a_->to_isr();
|
||||||
this->pin_b_->setup();
|
this->pin_b_->setup();
|
||||||
|
@ -142,6 +158,18 @@ void RotaryEncoderSensor::dump_config() {
|
||||||
LOG_PIN(" Pin A: ", this->pin_a_);
|
LOG_PIN(" Pin A: ", this->pin_a_);
|
||||||
LOG_PIN(" Pin B: ", this->pin_b_);
|
LOG_PIN(" Pin B: ", this->pin_b_);
|
||||||
LOG_PIN(" Pin I: ", this->pin_i_);
|
LOG_PIN(" Pin I: ", this->pin_i_);
|
||||||
|
|
||||||
|
const LogString *restore_mode = LOG_STR("");
|
||||||
|
switch (this->restore_mode_) {
|
||||||
|
case ROTARY_ENCODER_RESTORE_DEFAULT_ZERO:
|
||||||
|
restore_mode = LOG_STR("Restore (Defaults to zero)");
|
||||||
|
break;
|
||||||
|
case ROTARY_ENCODER_ALWAYS_ZERO:
|
||||||
|
restore_mode = LOG_STR("Always zero");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ESP_LOGCONFIG(TAG, " Restore Mode: %s", LOG_STR_ARG(restore_mode));
|
||||||
|
|
||||||
switch (this->store_.resolution) {
|
switch (this->store_.resolution) {
|
||||||
case ROTARY_ENCODER_1_PULSE_PER_CYCLE:
|
case ROTARY_ENCODER_1_PULSE_PER_CYCLE:
|
||||||
ESP_LOGCONFIG(TAG, " Resolution: 1 Pulse Per Cycle");
|
ESP_LOGCONFIG(TAG, " Resolution: 1 Pulse Per Cycle");
|
||||||
|
@ -190,6 +218,9 @@ void RotaryEncoderSensor::loop() {
|
||||||
}
|
}
|
||||||
int counter = this->store_.counter;
|
int counter = this->store_.counter;
|
||||||
if (this->store_.last_read != counter || this->publish_initial_value_) {
|
if (this->store_.last_read != counter || this->publish_initial_value_) {
|
||||||
|
if (this->restore_mode_ == ROTARY_ENCODER_RESTORE_DEFAULT_ZERO) {
|
||||||
|
this->rtc_.save(&counter);
|
||||||
|
}
|
||||||
this->store_.last_read = counter;
|
this->store_.last_read = counter;
|
||||||
this->publish_state(counter);
|
this->publish_state(counter);
|
||||||
this->publish_initial_value_ = false;
|
this->publish_initial_value_ = false;
|
||||||
|
@ -197,6 +228,9 @@ void RotaryEncoderSensor::loop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
float RotaryEncoderSensor::get_setup_priority() const { return setup_priority::DATA; }
|
float RotaryEncoderSensor::get_setup_priority() const { return setup_priority::DATA; }
|
||||||
|
void RotaryEncoderSensor::set_restore_mode(RotaryEncoderRestoreMode restore_mode) {
|
||||||
|
this->restore_mode_ = restore_mode;
|
||||||
|
}
|
||||||
void RotaryEncoderSensor::set_resolution(RotaryEncoderResolution mode) { this->store_.resolution = mode; }
|
void RotaryEncoderSensor::set_resolution(RotaryEncoderResolution mode) { this->store_.resolution = mode; }
|
||||||
void RotaryEncoderSensor::set_min_value(int32_t min_value) { this->store_.min_value = min_value; }
|
void RotaryEncoderSensor::set_min_value(int32_t min_value) { this->store_.min_value = min_value; }
|
||||||
void RotaryEncoderSensor::set_max_value(int32_t max_value) { this->store_.max_value = max_value; }
|
void RotaryEncoderSensor::set_max_value(int32_t max_value) { this->store_.max_value = max_value; }
|
||||||
|
|
|
@ -10,6 +10,12 @@
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace rotary_encoder {
|
namespace rotary_encoder {
|
||||||
|
|
||||||
|
/// All possible restore modes for the rotary encoder
|
||||||
|
enum RotaryEncoderRestoreMode {
|
||||||
|
ROTARY_ENCODER_RESTORE_DEFAULT_ZERO, /// try to restore counter, otherwise set to zero
|
||||||
|
ROTARY_ENCODER_ALWAYS_ZERO, /// do not restore counter, always set to zero
|
||||||
|
};
|
||||||
|
|
||||||
/// All possible resolutions for the rotary encoder
|
/// All possible resolutions for the rotary encoder
|
||||||
enum RotaryEncoderResolution {
|
enum RotaryEncoderResolution {
|
||||||
ROTARY_ENCODER_1_PULSE_PER_CYCLE =
|
ROTARY_ENCODER_1_PULSE_PER_CYCLE =
|
||||||
|
@ -40,6 +46,15 @@ class RotaryEncoderSensor : public sensor::Sensor, public Component {
|
||||||
void set_pin_a(InternalGPIOPin *pin_a) { pin_a_ = pin_a; }
|
void set_pin_a(InternalGPIOPin *pin_a) { pin_a_ = pin_a; }
|
||||||
void set_pin_b(InternalGPIOPin *pin_b) { pin_b_ = pin_b; }
|
void set_pin_b(InternalGPIOPin *pin_b) { pin_b_ = pin_b; }
|
||||||
|
|
||||||
|
/** Set the restore mode of the rotary encoder.
|
||||||
|
*
|
||||||
|
* By default (if possible) the last known counter state is restored. Otherwise the value 0 is used.
|
||||||
|
* Restoring the state can also be turned off.
|
||||||
|
*
|
||||||
|
* @param restore_mode The restore mode to use.
|
||||||
|
*/
|
||||||
|
void set_restore_mode(RotaryEncoderRestoreMode restore_mode);
|
||||||
|
|
||||||
/** Set the resolution of the rotary encoder.
|
/** Set the resolution of the rotary encoder.
|
||||||
*
|
*
|
||||||
* By default, this component will increment the counter by 1 with every A-B input cycle.
|
* By default, this component will increment the counter by 1 with every A-B input cycle.
|
||||||
|
@ -81,6 +96,8 @@ class RotaryEncoderSensor : public sensor::Sensor, public Component {
|
||||||
InternalGPIOPin *pin_b_;
|
InternalGPIOPin *pin_b_;
|
||||||
GPIOPin *pin_i_{nullptr}; /// Index pin, if this is not nullptr, the counter will reset to 0 once this pin is HIGH.
|
GPIOPin *pin_i_{nullptr}; /// Index pin, if this is not nullptr, the counter will reset to 0 once this pin is HIGH.
|
||||||
bool publish_initial_value_;
|
bool publish_initial_value_;
|
||||||
|
ESPPreferenceObject rtc_;
|
||||||
|
RotaryEncoderRestoreMode restore_mode_{ROTARY_ENCODER_RESTORE_DEFAULT_ZERO};
|
||||||
|
|
||||||
RotaryEncoderSensorStore store_{};
|
RotaryEncoderSensorStore store_{};
|
||||||
|
|
||||||
|
|
|
@ -14,9 +14,17 @@ from esphome.const import (
|
||||||
CONF_PIN_A,
|
CONF_PIN_A,
|
||||||
CONF_PIN_B,
|
CONF_PIN_B,
|
||||||
CONF_TRIGGER_ID,
|
CONF_TRIGGER_ID,
|
||||||
|
CONF_RESTORE_MODE,
|
||||||
)
|
)
|
||||||
|
|
||||||
rotary_encoder_ns = cg.esphome_ns.namespace("rotary_encoder")
|
rotary_encoder_ns = cg.esphome_ns.namespace("rotary_encoder")
|
||||||
|
|
||||||
|
RotaryEncoderRestoreMode = rotary_encoder_ns.enum("RotaryEncoderRestoreMode")
|
||||||
|
RESTORE_MODES = {
|
||||||
|
"RESTORE_DEFAULT_ZERO": RotaryEncoderRestoreMode.ROTARY_ENCODER_RESTORE_DEFAULT_ZERO,
|
||||||
|
"ALWAYS_ZERO": RotaryEncoderRestoreMode.ROTARY_ENCODER_ALWAYS_ZERO,
|
||||||
|
}
|
||||||
|
|
||||||
RotaryEncoderResolution = rotary_encoder_ns.enum("RotaryEncoderResolution")
|
RotaryEncoderResolution = rotary_encoder_ns.enum("RotaryEncoderResolution")
|
||||||
RESOLUTIONS = {
|
RESOLUTIONS = {
|
||||||
1: RotaryEncoderResolution.ROTARY_ENCODER_1_PULSE_PER_CYCLE,
|
1: RotaryEncoderResolution.ROTARY_ENCODER_1_PULSE_PER_CYCLE,
|
||||||
|
@ -72,6 +80,9 @@ CONFIG_SCHEMA = cv.All(
|
||||||
cv.Optional(CONF_MIN_VALUE): cv.int_,
|
cv.Optional(CONF_MIN_VALUE): cv.int_,
|
||||||
cv.Optional(CONF_MAX_VALUE): cv.int_,
|
cv.Optional(CONF_MAX_VALUE): cv.int_,
|
||||||
cv.Optional(CONF_PUBLISH_INITIAL_VALUE, default=False): cv.boolean,
|
cv.Optional(CONF_PUBLISH_INITIAL_VALUE, default=False): cv.boolean,
|
||||||
|
cv.Optional(CONF_RESTORE_MODE, default="RESTORE_DEFAULT_ZERO"): cv.enum(
|
||||||
|
RESTORE_MODES, upper=True, space="_"
|
||||||
|
),
|
||||||
cv.Optional(CONF_ON_CLOCKWISE): automation.validate_automation(
|
cv.Optional(CONF_ON_CLOCKWISE): automation.validate_automation(
|
||||||
{
|
{
|
||||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(
|
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(
|
||||||
|
@ -102,6 +113,7 @@ async def to_code(config):
|
||||||
pin_b = await cg.gpio_pin_expression(config[CONF_PIN_B])
|
pin_b = await cg.gpio_pin_expression(config[CONF_PIN_B])
|
||||||
cg.add(var.set_pin_b(pin_b))
|
cg.add(var.set_pin_b(pin_b))
|
||||||
cg.add(var.set_publish_initial_value(config[CONF_PUBLISH_INITIAL_VALUE]))
|
cg.add(var.set_publish_initial_value(config[CONF_PUBLISH_INITIAL_VALUE]))
|
||||||
|
cg.add(var.set_restore_mode(config[CONF_RESTORE_MODE]))
|
||||||
|
|
||||||
if CONF_PIN_RESET in config:
|
if CONF_PIN_RESET in config:
|
||||||
pin_i = await cg.gpio_pin_expression(config[CONF_PIN_RESET])
|
pin_i = await cg.gpio_pin_expression(config[CONF_PIN_RESET])
|
||||||
|
|
Loading…
Reference in a new issue