mirror of
https://github.com/esphome/esphome.git
synced 2024-12-26 15:34:53 +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() {
|
||||
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->store_.pin_a = this->pin_a_->to_isr();
|
||||
this->pin_b_->setup();
|
||||
|
@ -142,6 +158,18 @@ void RotaryEncoderSensor::dump_config() {
|
|||
LOG_PIN(" Pin A: ", this->pin_a_);
|
||||
LOG_PIN(" Pin B: ", this->pin_b_);
|
||||
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) {
|
||||
case ROTARY_ENCODER_1_PULSE_PER_CYCLE:
|
||||
ESP_LOGCONFIG(TAG, " Resolution: 1 Pulse Per Cycle");
|
||||
|
@ -190,6 +218,9 @@ void RotaryEncoderSensor::loop() {
|
|||
}
|
||||
int counter = this->store_.counter;
|
||||
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->publish_state(counter);
|
||||
this->publish_initial_value_ = false;
|
||||
|
@ -197,6 +228,9 @@ void RotaryEncoderSensor::loop() {
|
|||
}
|
||||
|
||||
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_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; }
|
||||
|
|
|
@ -10,6 +10,12 @@
|
|||
namespace esphome {
|
||||
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
|
||||
enum RotaryEncoderResolution {
|
||||
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_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.
|
||||
*
|
||||
* 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_;
|
||||
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_;
|
||||
ESPPreferenceObject rtc_;
|
||||
RotaryEncoderRestoreMode restore_mode_{ROTARY_ENCODER_RESTORE_DEFAULT_ZERO};
|
||||
|
||||
RotaryEncoderSensorStore store_{};
|
||||
|
||||
|
|
|
@ -14,9 +14,17 @@ from esphome.const import (
|
|||
CONF_PIN_A,
|
||||
CONF_PIN_B,
|
||||
CONF_TRIGGER_ID,
|
||||
CONF_RESTORE_MODE,
|
||||
)
|
||||
|
||||
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")
|
||||
RESOLUTIONS = {
|
||||
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_MAX_VALUE): cv.int_,
|
||||
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.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])
|
||||
cg.add(var.set_pin_b(pin_b))
|
||||
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:
|
||||
pin_i = await cg.gpio_pin_expression(config[CONF_PIN_RESET])
|
||||
|
|
Loading…
Reference in a new issue