Add rotation config parameter for stepper component.

This commit is contained in:
Christ van Willegen 2024-05-24 08:15:49 +02:00
parent 9d03f47233
commit 4e99433ae4
3 changed files with 58 additions and 2 deletions

View File

@ -9,6 +9,7 @@ from esphome.const import (
CONF_POSITION,
CONF_TARGET,
CONF_SPEED,
CONF_ROTATION,
)
from esphome.core import CORE, coroutine_with_priority
@ -22,6 +23,7 @@ ReportPositionAction = stepper_ns.class_("ReportPositionAction", automation.Acti
SetSpeedAction = stepper_ns.class_("SetSpeedAction", automation.Action)
SetAccelerationAction = stepper_ns.class_("SetAccelerationAction", automation.Action)
SetDecelerationAction = stepper_ns.class_("SetDecelerationAction", automation.Action)
SetRotationAction = stepper_ns.class_("SetRotationAction", automation.Action)
def validate_acceleration(value):
@ -66,11 +68,27 @@ def validate_speed(value):
return value
def validate_rotation(value):
value = cv.string(value)
if value == "both":
return 0
if value == "cw" or value == "clockwise":
return 1
if value == "ccw" or value == "counterclockwise" or value == "counter-clockwise":
return -1
raise cv.Invalid(f"Expected rotation as 'both', 'cw', 'ccw', 'clockwise', 'counterclockwise', 'counter-clockwise', got {value}")
STEPPER_SCHEMA = cv.Schema(
{
cv.Required(CONF_MAX_SPEED): validate_speed,
cv.Optional(CONF_ACCELERATION, default="inf"): validate_acceleration,
cv.Optional(CONF_DECELERATION, default="inf"): validate_acceleration,
cv.Optional(CONF_ROTATION, default="both"): validate_rotation,
}
)
@ -82,6 +100,8 @@ async def setup_stepper_core_(stepper_var, config):
cg.add(stepper_var.set_deceleration(config[CONF_DECELERATION]))
if CONF_MAX_SPEED in config:
cg.add(stepper_var.set_max_speed(config[CONF_MAX_SPEED]))
if CONF_ROTATION in config:
cg.add(stepper_var.set_rotation(config[CONF_ROTATION]))
async def register_stepper(var, config):
@ -180,6 +200,24 @@ async def stepper_set_deceleration_to_code(config, action_id, template_arg, args
return var
@automation.register_action(
"stepper.set_rotation",
SetRotationAction,
cv.Schema(
{
cv.Required(CONF_ID): cv.use_id(Stepper),
cv.Required(CONF_ROTATION): cv.templatable(validate_rotation),
}
),
)
async def stepper_set_rotation_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg, paren)
template_ = await cg.templatable(config[CONF_ROTATION], args, cg.string_)
cg.add(var.set_rotation(template_))
return var
@coroutine_with_priority(100.0)
async def to_code(config):
cg.add_global(stepper_ns.using)

View File

@ -38,7 +38,7 @@ int32_t Stepper::should_step_() {
// assumes this method is called in a constant interval
uint32_t dt = now - this->last_step_;
if (dt >= (1 / this->current_speed_) * 1e6f) {
int32_t mag = this->target_position > this->current_position ? 1 : -1;
int32_t mag = (rotation_ == 0 ? (this->target_position > this->current_position ? 1 : -1) : rotation_);
this->last_step_ = now;
this->current_position += mag;
return mag;

View File

@ -10,7 +10,8 @@ namespace stepper {
#define LOG_STEPPER(this) \
ESP_LOGCONFIG(TAG, " Acceleration: %.0f steps/s^2", this->acceleration_); \
ESP_LOGCONFIG(TAG, " Deceleration: %.0f steps/s^2", this->deceleration_); \
ESP_LOGCONFIG(TAG, " Max Speed: %.0f steps/s", this->max_speed_);
ESP_LOGCONFIG(TAG, " Max Speed: %.0f steps/s", this->max_speed_); \
ESP_LOGCONFIG(TAG, " Rotation: %s", this->rotation_);
class Stepper {
public:
@ -19,6 +20,7 @@ class Stepper {
void set_acceleration(float acceleration) { this->acceleration_ = acceleration; }
void set_deceleration(float deceleration) { this->deceleration_ = deceleration; }
void set_max_speed(float max_speed) { this->max_speed_ = max_speed; }
void set_rotation(int rotation) { this->rotation_ = rotation; }
virtual void on_update_speed() {}
bool has_reached_target() { return this->current_position == this->target_position; }
@ -33,6 +35,7 @@ class Stepper {
float deceleration_{1e6f};
float current_speed_{0.0f};
float max_speed_{1e6f};
int rotation_{0};
uint32_t last_calculation_{0};
uint32_t last_step_{0};
};
@ -107,5 +110,20 @@ template<typename... Ts> class SetDecelerationAction : public Action<Ts...> {
Stepper *parent_;
};
template<typename... Ts> class SetRotationAction : public Action<Ts...> {
public:
explicit SetRotationAction(Stepper *parent) : parent_(parent) {}
TEMPLATABLE_VALUE(int, rotation);
void play(Ts... x) override {
int rotation = this->rotation_.value(x...);
this->parent_->set_rotation(rotation);
}
protected:
Stepper *parent_;
};
} // namespace stepper
} // namespace esphome