2018-10-26 22:30:24 +02:00
|
|
|
Stepper Component
|
|
|
|
=================
|
|
|
|
|
2018-11-14 22:12:27 +01:00
|
|
|
.. seo::
|
2019-02-16 23:25:23 +01:00
|
|
|
:description: Instructions for setting up stepper motor drivers in ESPHome
|
2021-11-16 03:19:33 +01:00
|
|
|
:image: folder-open.svg
|
2018-11-14 22:12:27 +01:00
|
|
|
:keywords: stepper motor, stepper driver, a4988
|
|
|
|
|
2019-02-16 23:25:23 +01:00
|
|
|
The ``stepper`` component allows you to use stepper motors with ESPHome.
|
2018-10-26 22:30:24 +02:00
|
|
|
Currently only the A4988 stepper driver
|
|
|
|
(`datasheet <https://www.pololu.com/file/0J450/a4988_DMOS_microstepping_driver_with_translator.pdf>`__)
|
2019-01-06 18:56:14 +01:00
|
|
|
and ULN2003 (`datasheet <http://www.ti.com/lit/ds/symlink/uln2003a.pdf>`__) are supported.
|
|
|
|
|
2019-03-13 16:17:05 +01:00
|
|
|
.. note::
|
|
|
|
|
|
|
|
This component will not show up in the Home Assistant front-end automatically because
|
|
|
|
Home Assistant doesn't have support for steppers. Please see :ref:`stepper-ha-config`.
|
|
|
|
|
2021-02-20 22:02:46 +01:00
|
|
|
.. _base_stepper_config:
|
|
|
|
|
|
|
|
Base Stepper Configuration
|
|
|
|
--------------------------
|
|
|
|
|
|
|
|
All stepper configuration schemas inherit these options.
|
|
|
|
|
|
|
|
Configuration variables:
|
|
|
|
|
|
|
|
- **max_speed** (**Required**, float): The maximum speed in ``steps/s`` (steps per seconds) to drive the
|
|
|
|
stepper at. Note most steppers can't step properly with speeds higher than 250 steps/s.
|
|
|
|
- **acceleration** (*Optional*, float): The acceleration in ``steps/s^2`` (steps per seconds squared)
|
|
|
|
to use when starting to move. The default is ``inf`` which means infinite acceleration, so the
|
|
|
|
stepper will try to drive with the full speed immediately. This value is helpful if that first motion of
|
|
|
|
the motor is too jerky for what it's moving. If you make this a small number, it will take the motor a
|
|
|
|
moment to get up to speed.
|
|
|
|
- **deceleration** (*Optional*, float): The same as ``acceleration``, but for when the motor is decelerating
|
|
|
|
shortly before reaching the set position. Defaults to ``inf`` (immediate deceleration).
|
|
|
|
|
|
|
|
A4988 Component
|
|
|
|
---------------
|
2018-10-26 22:30:24 +02:00
|
|
|
|
2021-05-20 16:00:53 +02:00
|
|
|
Put this code into the configuration file on ESPHome for this device.
|
2020-12-21 01:55:44 +01:00
|
|
|
|
2018-11-19 18:32:16 +01:00
|
|
|
.. code-block:: yaml
|
2018-10-26 22:30:24 +02:00
|
|
|
|
|
|
|
stepper:
|
|
|
|
- platform: a4988
|
|
|
|
id: my_stepper
|
|
|
|
step_pin: D0
|
|
|
|
dir_pin: D1
|
|
|
|
max_speed: 250 steps/s
|
|
|
|
|
|
|
|
# Optional:
|
|
|
|
sleep_pin: D2
|
|
|
|
acceleration: inf
|
|
|
|
deceleration: inf
|
|
|
|
|
|
|
|
|
|
|
|
Configuration variables:
|
|
|
|
|
|
|
|
- **id** (**Required**, :ref:`config-id`): Specify the ID of the stepper so that you can control it.
|
|
|
|
- **step_pin** (**Required**, :ref:`Pin Schema <config-pin_schema>`): The ``STEP`` pin of the A4988
|
|
|
|
stepper driver.
|
|
|
|
- **dir_pin** (**Required**, :ref:`Pin Schema <config-pin_schema>`): The ``DIRECTION`` pin of the A4988
|
|
|
|
stepper driver.
|
|
|
|
- **sleep_pin** (*Optional*, :ref:`Pin Schema <config-pin_schema>`): Optionally also use the ``SLEEP`` pin
|
|
|
|
of the A4988 stepper driver. If specified, the driver will be put into sleep mode as soon as the stepper
|
|
|
|
reaches the target steps.
|
2021-02-20 22:02:46 +01:00
|
|
|
|
|
|
|
- All other from :ref:`base_stepper_config`.
|
2018-10-26 22:30:24 +02:00
|
|
|
|
|
|
|
.. note::
|
|
|
|
|
|
|
|
If the stepper is driving in the wrong direction, you can invert the ``dir_pin``:
|
|
|
|
|
2018-11-19 18:32:16 +01:00
|
|
|
.. code-block:: yaml
|
2018-10-26 22:30:24 +02:00
|
|
|
|
|
|
|
stepper:
|
|
|
|
- platform: a4988
|
|
|
|
# ...
|
|
|
|
dir_pin:
|
|
|
|
number: D1
|
2021-07-28 23:56:11 +02:00
|
|
|
inverted: true
|
2018-10-26 22:30:24 +02:00
|
|
|
|
2021-02-20 22:02:46 +01:00
|
|
|
ULN2003 Component
|
|
|
|
-----------------
|
2019-01-06 18:56:14 +01:00
|
|
|
|
2020-12-21 01:55:44 +01:00
|
|
|
Put this code into the configuration file on ESPHome for this device.
|
|
|
|
|
2019-01-06 18:56:14 +01:00
|
|
|
.. code-block:: yaml
|
|
|
|
|
|
|
|
# Example configuration entry
|
|
|
|
stepper:
|
|
|
|
- platform: uln2003
|
|
|
|
id: my_stepper
|
|
|
|
pin_a: D0
|
|
|
|
pin_b: D1
|
|
|
|
pin_c: D2
|
|
|
|
pin_d: D3
|
|
|
|
max_speed: 250 steps/s
|
|
|
|
|
|
|
|
# Optional:
|
|
|
|
acceleration: inf
|
|
|
|
deceleration: inf
|
|
|
|
|
|
|
|
|
|
|
|
Configuration variables:
|
|
|
|
|
|
|
|
- **id** (**Required**, :ref:`config-id`): Specify the ID of the stepper so that you can control it.
|
2021-02-20 22:02:46 +01:00
|
|
|
- **pin_a** (**Required**, :ref:`Pin Schema <config-pin_schema>`): The pin **a** of the stepper control board.
|
|
|
|
- **pin_b** (**Required**, :ref:`Pin Schema <config-pin_schema>`): The pin **b** of the stepper control board.
|
|
|
|
- **pin_c** (**Required**, :ref:`Pin Schema <config-pin_schema>`): The pin **c** of the stepper control board.
|
|
|
|
- **pin_d** (**Required**, :ref:`Pin Schema <config-pin_schema>`): The pin **d** of the stepper control board.
|
2019-01-06 18:56:14 +01:00
|
|
|
- **sleep_when_done** (*Optional*, boolean): Whether to turn off all coils when the stepper has
|
|
|
|
reached the target position
|
|
|
|
- **step_mode** (*Optional*, string): The step mode to operate the motor with. One of:
|
|
|
|
|
|
|
|
- ``FULL_STEP`` (Default)
|
|
|
|
- ``HALF_STEP``
|
|
|
|
- ``WAVE_DRIVE``
|
|
|
|
|
2021-02-20 22:02:46 +01:00
|
|
|
- All other from :ref:`base_stepper_config`.
|
2018-10-26 22:30:24 +02:00
|
|
|
|
|
|
|
.. _stepper-set_target_action:
|
|
|
|
|
|
|
|
``stepper.set_target`` Action
|
|
|
|
-----------------------------
|
|
|
|
|
|
|
|
To use your stepper motor in :ref:`automations <automation>` or templates, you can use this action to set the target
|
|
|
|
position (in steps). The stepper will always run towards the target position and stop once it has reached the target.
|
|
|
|
|
2018-11-19 18:32:16 +01:00
|
|
|
.. code-block:: yaml
|
2018-10-26 22:30:24 +02:00
|
|
|
|
|
|
|
on_...:
|
|
|
|
then:
|
|
|
|
- stepper.set_target:
|
|
|
|
id: my_stepper
|
|
|
|
target: 250
|
|
|
|
|
|
|
|
# Templated
|
|
|
|
- stepper.set_target:
|
|
|
|
id: my_stepper
|
|
|
|
target: !lambda |-
|
2019-01-13 15:49:06 +01:00
|
|
|
if (id(my_binary_sensor).state) {
|
2018-10-26 22:30:24 +02:00
|
|
|
return 1000;
|
|
|
|
} else {
|
|
|
|
return -1000;
|
|
|
|
}
|
|
|
|
|
|
|
|
Configuration options:
|
|
|
|
|
|
|
|
- **id** (**Required**, :ref:`config-id`): The ID of the stepper.
|
2021-02-20 22:02:46 +01:00
|
|
|
- **target** (**Required**, int, :ref:`templatable <config-templatable>`): The target position in steps.
|
2018-10-26 22:30:24 +02:00
|
|
|
|
2019-03-13 16:17:05 +01:00
|
|
|
.. warning::
|
|
|
|
|
|
|
|
This turns the stepper to an absolute position! To have the servo move *relative* to the current
|
|
|
|
position, first reset the current position and then set the target to the relative value.
|
|
|
|
|
|
|
|
.. code-block:: yaml
|
|
|
|
|
|
|
|
on_...:
|
|
|
|
then:
|
|
|
|
# Move 150 steps forward
|
|
|
|
- stepper.report_position:
|
|
|
|
id: my_stepper
|
|
|
|
position: 0
|
2019-05-26 10:27:08 +02:00
|
|
|
- stepper.set_target:
|
2019-03-13 16:17:05 +01:00
|
|
|
id: my_stepper
|
|
|
|
target: 150
|
|
|
|
|
2018-10-26 22:30:24 +02:00
|
|
|
.. _stepper-report_position_action:
|
|
|
|
|
|
|
|
``stepper.report_position`` Action
|
|
|
|
----------------------------------
|
|
|
|
|
|
|
|
All steppers start out with a target and current position of ``0`` on boot. However, if you for example want to home
|
|
|
|
a stepper motor, it can be useful to **report** the stepper where it is currently at.
|
|
|
|
|
|
|
|
With this action, you can set the stepper's internal position counter to a specific value (in steps). Please note
|
|
|
|
that reporting the position can create unexpected moves of the stepper. For example, if the stepper's target and
|
|
|
|
current position is at 1000 steps and you "report" a position of 0, the stepper will move 1000 steps forward to match
|
|
|
|
the target again.
|
|
|
|
|
2018-11-19 18:32:16 +01:00
|
|
|
.. code-block:: yaml
|
2018-10-26 22:30:24 +02:00
|
|
|
|
|
|
|
on_...:
|
|
|
|
then:
|
|
|
|
- stepper.report_position:
|
|
|
|
id: my_stepper
|
|
|
|
position: 250
|
|
|
|
# It's best to call set_target directly after report_position, so that the stepper doesn't move
|
|
|
|
- stepper.set_target:
|
|
|
|
id: my_stepper
|
|
|
|
target: 250
|
|
|
|
|
|
|
|
# Templated
|
|
|
|
- stepper.report_position:
|
|
|
|
id: my_stepper
|
|
|
|
position: !lambda |-
|
2019-01-13 15:49:06 +01:00
|
|
|
if (id(my_binary_sensor).state) {
|
2018-10-26 22:30:24 +02:00
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
return -1000;
|
|
|
|
}
|
|
|
|
|
2021-02-20 22:02:46 +01:00
|
|
|
Configuration variables:
|
2018-10-26 22:30:24 +02:00
|
|
|
|
|
|
|
- **id** (**Required**, :ref:`config-id`): The ID of the stepper.
|
2021-02-20 22:02:46 +01:00
|
|
|
- **position** (**Required**, int, :ref:`templatable <config-templatable>`): The position to report in steps.
|
2018-10-26 22:30:24 +02:00
|
|
|
|
2019-05-12 22:44:59 +02:00
|
|
|
.. _stepper-set_speed_action:
|
|
|
|
|
|
|
|
``stepper.set_speed`` Action
|
|
|
|
----------------------------
|
|
|
|
|
|
|
|
This :ref:`Action <config-action>` allows you to set the speed of a stepper at runtime.
|
|
|
|
|
|
|
|
.. code-block:: yaml
|
|
|
|
|
|
|
|
on_...:
|
|
|
|
- stepper.set_speed:
|
|
|
|
id: my_stepper
|
|
|
|
speed: 250 steps/s
|
|
|
|
|
|
|
|
Configuration variables:
|
|
|
|
|
|
|
|
- **id** (**Required**, :ref:`config-id`): The ID of the stepper.
|
|
|
|
- **speed** (**Required**, :ref:`templatable <config-templatable>`, float): The speed
|
|
|
|
in ``steps/s`` (steps per seconds) to drive the stepper at.
|
|
|
|
|
2021-07-05 03:22:54 +02:00
|
|
|
.. _stepper-set_acceleration_action:
|
|
|
|
|
|
|
|
``stepper.set_acceleration`` Action
|
|
|
|
-----------------------------------
|
|
|
|
|
|
|
|
This :ref:`Action <config-action>` allows you to set the acceleration of a stepper at runtime.
|
|
|
|
|
|
|
|
.. code-block:: yaml
|
|
|
|
|
|
|
|
on_...:
|
|
|
|
- stepper.set_acceleration:
|
|
|
|
id: my_stepper
|
2022-03-11 03:00:26 +01:00
|
|
|
acceleration: 250 steps/s^2
|
2021-07-05 03:22:54 +02:00
|
|
|
|
|
|
|
Configuration variables:
|
|
|
|
|
|
|
|
- **id** (**Required**, :ref:`config-id`): The ID of the stepper.
|
|
|
|
- **acceleration** (**Required**, :ref:`templatable <config-templatable>`, float): The acceleration
|
|
|
|
in ``steps/s^2`` (steps per seconds squared) to use when starting to move.
|
|
|
|
|
|
|
|
.. _stepper-set_deceleration_action:
|
|
|
|
|
|
|
|
``stepper.set_deceleration`` Action
|
|
|
|
-----------------------------------
|
|
|
|
|
|
|
|
This :ref:`Action <config-action>` allows you to set the deceleration of a stepper at runtime.
|
|
|
|
|
|
|
|
.. code-block:: yaml
|
|
|
|
|
|
|
|
on_...:
|
|
|
|
- stepper.set_deceleration:
|
|
|
|
id: my_stepper
|
2022-03-11 03:00:26 +01:00
|
|
|
deceleration: 250 steps/s^2
|
2021-07-05 03:22:54 +02:00
|
|
|
|
|
|
|
Configuration variables:
|
|
|
|
|
|
|
|
- **id** (**Required**, :ref:`config-id`): The ID of the stepper.
|
|
|
|
- **deceleration** (**Required**, :ref:`templatable <config-templatable>`, float): The same as ``acceleration``,
|
|
|
|
but for when the motor is decelerating shortly before reaching the set position.
|
|
|
|
|
2019-03-13 16:17:05 +01:00
|
|
|
.. _stepper-ha-config:
|
|
|
|
|
|
|
|
Home Assistant Configuration
|
|
|
|
----------------------------
|
|
|
|
|
2021-02-20 22:02:46 +01:00
|
|
|
This component will not show up in the Home Assistant front-end (Overview) automatically because
|
2020-12-21 01:55:44 +01:00
|
|
|
Home Assistant does not support steppers natively.
|
|
|
|
|
|
|
|
You can add the stepper component code below to your Home Assistant configuration (``configuration.yaml``) to
|
2021-02-20 22:02:46 +01:00
|
|
|
be able to control the stepper from the front-end.
|
2019-03-13 16:17:05 +01:00
|
|
|
|
|
|
|
.. code-block:: yaml
|
|
|
|
|
2020-12-21 01:55:44 +01:00
|
|
|
# Add a slider control to Home Assistant to set an integer value
|
2019-03-13 16:17:05 +01:00
|
|
|
input_number:
|
|
|
|
stepper_control:
|
|
|
|
name: Stepper Control
|
|
|
|
initial: 0
|
|
|
|
min: -1000
|
|
|
|
max: 1000
|
|
|
|
step: 1
|
|
|
|
mode: slider
|
2021-02-20 22:02:46 +01:00
|
|
|
|
2020-12-21 01:55:44 +01:00
|
|
|
# Do something when the slider changes
|
2019-03-13 16:17:05 +01:00
|
|
|
automation:
|
|
|
|
- alias: Write Stepper Value to ESP
|
|
|
|
trigger:
|
|
|
|
platform: state
|
|
|
|
entity_id: input_number.stepper_control
|
|
|
|
action:
|
|
|
|
# Replace livingroom with the name you gave the ESP
|
|
|
|
- service: esphome.livingroom_control_stepper
|
|
|
|
data_template:
|
|
|
|
target: '{{ trigger.to_state.state | int }}'
|
|
|
|
|
2021-02-20 22:02:46 +01:00
|
|
|
In the above code, "stepper_control" is the ID of a numeric input field. It must be unique and it is
|
|
|
|
used in the automation section as a reference name. The display name for this field is in
|
|
|
|
stepper_control's ``name`` key.
|
2020-12-21 01:55:44 +01:00
|
|
|
|
2021-02-20 22:02:46 +01:00
|
|
|
If you want your user interface to give you more control over your stepper controller, such as
|
2020-12-21 01:55:44 +01:00
|
|
|
setting the acceleration, deceleration, etc, then you can add more input fields after ``stepper_control``
|
|
|
|
but before ``automation``. They can be a simple number-entry field (mode: box) or a slider like this.
|
|
|
|
Each of these extra input fields needs an associated input parameter defined on the ESPHome device's
|
|
|
|
API service.
|
|
|
|
|
|
|
|
The automation section tells Home Assistant what to do when the slider changes. It needs a trigger
|
2021-02-20 22:02:46 +01:00
|
|
|
(state of the ``stepper_control`` slider) and an action. In the trigger section, ``entity_id`` must refer
|
2020-12-21 01:55:44 +01:00
|
|
|
back to the configuration ID that triggers the automation. For us, that is the ``stepper_control``
|
|
|
|
field in the ``input_number`` item. That's why the value is ``input_number.stepper_control``.
|
|
|
|
|
|
|
|
In the action section, the service name is vital to get right: it's the glue that connects Home Automation's
|
|
|
|
front-end to the ESPHome device configuration. While you might expect the syntax to be ``esphome.<your_device>.<api_service>``,
|
|
|
|
the correct syntax is to join the device ID to the API service ID with an underscore,
|
|
|
|
as in ``esphome.livingroom_control_stepper`` where "Livingroom" is a device in ESPHome and "control_stepper" is an
|
|
|
|
API service for that device.
|
|
|
|
|
2021-02-20 22:02:46 +01:00
|
|
|
The template string is used to get the "state" value from the ``target`` field (defined in the target section) on the
|
2020-12-21 01:55:44 +01:00
|
|
|
``input_number`` component of the Home Assistant front-end. This value is then passed to the API service as defined in
|
|
|
|
the ESPHome device's configuration. The ``data_template`` section lists one value for each of the input parameters on
|
|
|
|
the service being called by the automation. In our case, the ESPHome device has an API service with a single parameter,
|
|
|
|
"target". If you called this "my_target", then the last line above should be ``my_target: '{{ trigger.to_state.state | int }}'``.
|
|
|
|
Getting this linkage right is very important.
|
|
|
|
|
|
|
|
The following code needs to go in the ESPHome configuration file for this device. Above, we mention "API service"
|
|
|
|
a lot. This code is where that is defined. You may have already added it (or something similar). Note
|
2021-02-20 22:02:46 +01:00
|
|
|
that the input variable for the ``control_stepper`` service is called ``target``. That's what matches with the
|
2020-12-21 01:55:44 +01:00
|
|
|
automation configuration above. Also note that the variable ``target`` is defined as an integer. That means it
|
|
|
|
must be an integer number, not a string.
|
|
|
|
|
2019-03-13 16:17:05 +01:00
|
|
|
.. code-block:: yaml
|
|
|
|
|
|
|
|
# ESPHome configuration
|
|
|
|
api:
|
|
|
|
services:
|
|
|
|
- service: control_stepper
|
|
|
|
variables:
|
|
|
|
target: int
|
|
|
|
then:
|
|
|
|
- stepper.set_target:
|
|
|
|
id: my_stepper
|
|
|
|
target: !lambda 'return target;'
|
|
|
|
|
|
|
|
stepper:
|
|
|
|
- platform: ...
|
|
|
|
# [...] stepper config
|
|
|
|
id: my_stepper
|
|
|
|
|
2019-04-09 11:05:03 +02:00
|
|
|
.. _stepper-lambda_calls:
|
|
|
|
|
|
|
|
lambda calls
|
|
|
|
------------
|
|
|
|
|
|
|
|
From :ref:`lambdas <config-lambda>`, you can call several methods on stepper motors to do some
|
|
|
|
advanced stuff (see the full API Reference for more info).
|
|
|
|
|
2019-10-21 20:35:56 +02:00
|
|
|
- ``set_target``: Set the target position of the motor as an integer.
|
2019-04-09 11:05:03 +02:00
|
|
|
|
|
|
|
.. code-block:: cpp
|
|
|
|
|
|
|
|
// Argument is integer (signed int)
|
|
|
|
// Set the (absolute) target position to 250 steps
|
|
|
|
id(my_stepper).set_target(250);
|
|
|
|
|
2019-10-21 20:35:56 +02:00
|
|
|
- ``report_position``: Report the current position as an integer.
|
2019-04-09 11:05:03 +02:00
|
|
|
|
|
|
|
.. code-block:: cpp
|
|
|
|
|
|
|
|
// Report the (absolute) current position as 250 steps
|
|
|
|
id(my_stepper).report_position(250);
|
|
|
|
|
2019-10-21 20:35:56 +02:00
|
|
|
- ``current_position``: Get the current position of the stepper as an integer.
|
2019-04-09 11:05:03 +02:00
|
|
|
|
|
|
|
.. code-block:: cpp
|
|
|
|
|
|
|
|
int pos = id(my_stepper).current_position;
|
|
|
|
|
|
|
|
|
2019-10-21 20:35:56 +02:00
|
|
|
- ``target_position``: Get the set target position of the stepper as an integer.
|
2019-04-09 11:05:03 +02:00
|
|
|
|
|
|
|
.. code-block:: cpp
|
|
|
|
|
|
|
|
int pos = id(my_stepper).target_position;
|
2019-03-13 16:17:05 +01:00
|
|
|
|
2018-10-26 22:30:24 +02:00
|
|
|
See Also
|
|
|
|
--------
|
|
|
|
|
2019-02-07 13:54:45 +01:00
|
|
|
- :apiref:`stepper/stepper.h`
|
|
|
|
- :ghedit:`Edit`
|