I like this global variable approach but I’m having a bit of trouble figuring out how the position is suppose to be used to restore the state. Any chance you could provide a full file example?
Hi @gijsje, I am trying to build a similar thing. How exactly did you connect D5, D6 & D7 buttons as INPUT_PULLUP:
D5—3k3 Resistor----switch-----3.3 V ?
The INPUT_PULLUP
is done within the ESP, you don’t have to use resistors. Since this is using PULLUP I would say that the gijsje is connecting the other side of the switch to ground.
Yes, thnx
D5----switch-----Gnd
That is it
Did a bit of an upgrade over the weekend
I replaced my 12V 48BYJ-28 (modded to bi-polar with an A4988 stepper driver) to a NEMA 17 (17HS4401). The 48BYJ-28 was a bit underpowered for the blinds I have (blackout blinds; 210cm wide, have to unroll 180cm => quite heavy as you can imagine) and the 48BYJ-28 did the job; but very slowly with a 3:1 reduction planetary gearbox
With the new stepper it’s able to roll up/down the blinds in ~20sec, with the 48BYJ-28 it was ~8min…
But, that’s not the reason I’m posting here!
Since I was updating the system, I went from ESPHome 1.4.3 to a 1.5.0-dev branch for shits and giggles and found a new neat little feature. So, you can expect this to work when ESPHome 1.5.0 drops It’s currently undocumented (even in the beta/next documentation of ESPHome) but it’s there and it works.
The cover template now has a new action: position_action. So I got it all set up and working, ESPHome is reporting the position back to Home Assistant and when I set the position in the HA cover it’s correctly interpreted by ESPHome.
The only minor annoyance, it’s not setable directly from the frontend You have to click the cover entity in HA to get to the position slider:
I found a thread from a few years ago that describes the same problem. I’m gonna see how I tackle this cause I want to keep my configs clean and simple. So if I can do it without any extra input & automation that would be perfect
Very nice.
Still need to hang my blinds tho
I had the problem that with the nemo steppers the blinds would not stay up because of the weight.
What did you do about that?
You got 2 options: don’t use sleep but then the stepper will constantly be adjusting. This was something I didn’t want.
So I did a mix-and-match. The original cord-system of the blinds were unusable but I still had the mounting brackets from an old Ikea Isdans (old model) so I used the spring-loaded side of that one (and attached the chain, just in case the elctronics fail) and put the motor on the other side. I did have to make a new 3:1 gear reduction planetary gearbox for the NEMA since it didn’t have enough torque to overcome the springs tension…
So (like some others in this thread have done aswell) you can just use the spring-loaded side of the blinds you are using. Depending on the model, you can bend the spring or if it has multiple springs just remove some. I went with the planetary gearbox because I had do use the full tension of the spring to hold my heavy blinds in place.
what config are you using?
A mashup from things that have been posted here with my own tweaks
esphome:
name: blinds
platform: ESP8266
board: d1_mini
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_pw
fast_connect: true
manual_ip:
static_ip: !secret blinds_ip
subnet: !secret net1_subnet
dns1: !secret net1_dns1
dns2: !secret net1_dns2
gateway: !secret net1_gw
# Enable logging
logger:
# Enable Home Assistant API
api:
password: !secret HA_API
services:
- service: control_stepper
variables:
target: float
then:
- stepper.set_target:
id: my_stepper
target: !lambda "return target;"
- cover.template.publish:
id: blinds
position: !lambda "return 1 - ((target) / id(stepper_steps));"
ota:
password: !secret OTA_pw
globals:
- id: stepper_steps
type: int
initial_value: '11600'
- id: stepper_position
type: float
initial_value: '0'
- id: stepper_state
type: int
initial_value: '0'
binary_sensor:
- platform: gpio
pin: D8
name: "Button"
filters:
on_press:
then:
- lambda: |
if (id(stepper_state) == 0) {
//shade is stopped
if (((id(stepper_position) < (id(stepper_steps) / 2)) || (id(stepper_position) == id(stepper_steps))) && (id(stepper_position) > 0)) {
id(blinds).open();
} else {
id(blinds).close();
}
} else {
//shade is moving
id(blinds).stop();
}
cover:
- platform: template
name: "Blinds"
id: blinds
open_action:
- globals.set:
id: stepper_state
value: '1'
- stepper.set_target:
id: my_stepper
target: 0
- delay: !lambda "return (id(my_stepper).current_position / id(stepper_steps)) * 30000;"
- globals.set:
id: stepper_position
value: !lambda "return id(my_stepper).target_position;"
- globals.set:
id: stepper_state
value: '0'
close_action:
- globals.set:
id: stepper_state
value: '1'
- stepper.set_target:
id: my_stepper
target: !lambda "return id(stepper_steps);"
- delay: !lambda "return (1 - (id(my_stepper).current_position / id(stepper_steps))) * 30000;"
- globals.set:
id: stepper_position
value: !lambda "return id(my_stepper).target_position;"
- globals.set:
id: stepper_state
value: '0'
stop_action:
- stepper.set_target:
id: my_stepper
target: !lambda "return id(my_stepper).current_position;"
- globals.set:
id: stepper_position
value: !lambda "return id(my_stepper).current_position;"
- globals.set:
id: stepper_state
value: '0'
- cover.template.publish:
id: blinds
position: !lambda "return 1 - (id(stepper_position) / id(stepper_steps));"
position_action:
- stepper.set_target:
id: my_stepper
target: !lambda "return id(stepper_steps) * (1 - pos);"
optimistic: true
assumed_state: true
has_position: true
stepper:
- platform: a4988
id: my_stepper
dir_pin: D1
step_pin: D2
max_speed: 500 steps/s
# Optional:
sleep_pin: D3
acceleration: inf
deceleration: inf
cheers. im using this setup https://www.youtube.com/watch?v=ocOO-8X_-Rk&list=WL&index=9&t=0s. but wonder if it could be converted over to the one you are using. im using different drivers to what esphome supports. i tried pluggin it onto my setup but just got whines from the motors. maybe its the dip switches or power issue.
@FF-Fox
Great work! I am also using 12V 48BYJ-28 steppers with ULN2003 driver board using this project https://www.thingiverse.com/thing:2392856
Also having a bigger blind (2-2.5m) which is to heavy for the 12V 48BYJ-28.
Ordered the same NEMA 17HS4401 you are using and the DRV8825 driver board (https://nl.aliexpress.com/item/33010878323.html) but that driver isn’t supported by ESPHome.
Two questions:
- You are using A4988 with success? Not the DRV8825 because they are not supported by ESPHome, or did you (also) have other reasons using another?
- Based on your description I find it quite hard to understand how you mount the stepper and other stuff. Are you able to post some pictues and share your gearbox? Thanks!
Yeah, I used the a4988 driver board, as you can see in my ESPHome code:
platform: a4988
I tried it with the 12V 48BYJ-28 stepper in unipolar mode with ULN2003 driver board, too slow/underpowered even with a gearbox.
Then I modded the stepper tot bipolar and used the a4988 driver, still too slow/underpowered even with a gearbox.
The NEMA17 with a4988 driver did the job, but doesn’t have any holding torque when in sleep mode, so I added the spring-holding mechanism from another blind. But by doing so, the stepper was underpowered ^^
So final version is NEMA17 with the a4988 driver, a planetary gearbox and the spring-mechanism
The mounting/gearbox looks like this:
So for mounting:
Screw the bracket with the oval holes to the ceiling.
Insert stepper motor.
Slide casing over it (just for looks, to hide the stepper).
Put on the gearbox, screw into stepper at the 4 corners of the stepper.
@FF-Fox Thanks!
Did you also think about the possibility to remember the current steps position when powercycling/restarting the ESP? Maybe by saving the step position in HA and send it to the ESP when it comes online again?
Yup, thought about it and implemented it at first! but after some use, decided I didn’t really need it
Since I’m using a global var for stepper position, you can just add restore_value: yes
instead of initial_value: '0'
. But, keep in mind that this is written in flash memory every time and has a limited number of writes. That’s why I left it out. I still have my manual pull cord if a power failure would happen to position it (and it’s been in use for about 6months now in all its itterations and haven’t had a power failure or had to powercycle the esp).
Hi fox. Seems you find the best compromise for all problems (torque/heavy when stopped).
Could you share the stl for the printed part please?
Sure, If I got time this weekend, I’ll generate the STL’s.
I would really recommend to design this yourself, there are too many variables. The chances are pretty slim this will be what you want if you just download and print it. This is designed for:
- The tolerances of my printer
- The location I wanted it (ceiling mounted, also an impact on the screw holes of the mounting bracket)
- Material used (I reused the M4 screws, and since I wanted to use a cable tray it was moved a couple of millimeters so it would fit, …)
- My roller blinds, there is a small difference on inner diameter of the tube where the blinds are mounted on. This won’t fit on the Ikea blinds I had lying around
- Gear reduction I needed for the best speed-torque ratio
Uploaded the STL’s here.
Disclaimer from previous post still applies, I would recommend designing this yourself for a good fit.