Hi, I’m working on a project to automate some window roller shades. I’m essentially doing something very similar to this: roller blind connected to NEMA 17 stepper motor, driven by a TMC2209 driver, with a solenoid and ratchet mechanism to prevent the shade from falling when the motor is not energized.
However, instead of an Arduino in the above example, I’d like to use a D1 Mini with ESPHome so I can integrate into Home Assistant. I’ve basically got this up and running with one problem: when I include the solenoid output in my yaml code, it causes the stepper motor to stutter while running. When the solenoid is not included in the yaml code, it runs smoothly and everything is as expected.
So, I have a few theories on what might be happening:
- Calling the
wait_until
action is introducing an added delay at odd intervals (note that I needed to include this because it seems like the actions within the cover are non-blocking: withoutwait_until
, the solenoid would switch on, the motor would start turning, then the solenoid would immediately switch off - before the motor finished its movement.) - I am terrible at selecting hardware and the D1 mini is underpowered for this application, so it can’t handle the solenoid and stepper motor at the same time.
- Something else.
My first thought was that (1) was the problem, and I would need to build my own custom external component for this application. But being a mouth-breathing dunce with very limited coding skills, I didn’t want to waste a bunch of time trying to figure out external components if the problem is actually (2) or (3).
Does anyone have any insights into what might cause this? Please find my yaml code and wiring diagram attached below.
Thank you in advance!
substitutions:
name: esphome-web-2f9fd4
friendly_name: Living Room Left Blackout Shade
devicename: living_room_left_blackout_shade
height: '16000'
speed: '2000'
accel: '1000'
esphome:
name: ${name}
friendly_name: ${friendly_name}
name_add_mac_suffix: false
project:
name: esphome.web
version: '1.0'
esp8266:
board: esp01_1m
# Enable logging
logger:
# Enable Home Assistant API
api:
# Allow Over-The-Air updates
ota:
# Allow provisioning Wi-Fi via serial
improv_serial:
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Set up a wifi access point
ap:
ssid: "ssid"
password: "password"
# In combination with the `ap` this allows the user
# to provision wifi credentials to the device via WiFi AP.
captive_portal:
dashboard_import:
package_import_url: github://esphome/example-configs/esphome-web/esp8266.yaml@main
import_full_config: true
# To have a "next url" for improv serial
web_server:
cover:
- platform: template
name: None
id: ${devicename}
device_class: blind
open_action:
then:
- switch.turn_on: solenoid
- stepper.set_target:
id: my_stepper
target: ${height}
- sensor.template.publish:
id: position
state: !lambda return id(my_stepper).target_position;
- wait_until:
condition:
- lambda: |-
return id(my_stepper).current_position == id(my_stepper).target_position;
timeout: 30s
- switch.turn_off: solenoid
close_action:
then:
- switch.turn_on: solenoid
- stepper.set_target:
id: my_stepper
target: '0'
- sensor.template.publish:
id: position
state: !lambda return id(my_stepper).target_position;
- wait_until:
condition:
- lambda: |-
return id(my_stepper).current_position == id(my_stepper).target_position;
timeout: 30s
- switch.turn_off: solenoid
stop_action:
- then:
toggle_action:
then:
- if:
condition:
- lambda: |-
return id(my_stepper).current_position == 0;
then:
- switch.turn_on: solenoid
- stepper.set_target:
id: my_stepper
target: ${height}
- sensor.template.publish:
id: position
state: !lambda return id(my_stepper).target_position;
- wait_until:
condition:
- lambda: |-
return id(my_stepper).current_position == id(my_stepper).target_position;
timeout: 30s
- switch.turn_off: solenoid
else:
- switch.turn_on: solenoid
- stepper.set_target:
id: my_stepper
target: '0'
- sensor.template.publish:
id: position
state: !lambda return id(my_stepper).target_position;
- wait_until:
condition:
- lambda: |-
return id(my_stepper).current_position == id(my_stepper).target_position;
timeout: 30s
- switch.turn_off: solenoid
position_action:
- then:
assumed_state: true
has_position: true
sensor:
- platform: template
name: "Living Room Left Blackout Shade Position"
id: position
binary_sensor:
- platform: gpio
id: limit_switch
name: "Living Room Left Blackout Shade Manual Toggle"
pin: GPIO12
on_release:
then:
- cover.toggle: living_room_left_blackout_shade
switch:
- platform: gpio
pin: GPIO13
id: solenoid
stepper:
- platform: a4988
id: my_stepper
step_pin: GPIO14
dir_pin: GPIO4
sleep_pin:
number: GPIO5
inverted: true
max_speed: ${speed}
acceleration: ${accel}
deceleration: ${accel}