Motor on a roller blind - ESPHome version?

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 :+1:

That is it

1 Like

Did a bit of an upgrade over the weekend :slight_smile:

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 :stuck_out_tongue:
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 :slight_smile: 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 :frowning: You have to click the cover entity in HA to get to the position slider:
blinds_position

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 :slight_smile:

2 Likes

Never mind, minor annoyance gone!
Blinds_lovelace

With a little help of slider-entity-row :slight_smile:

1 Like

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 :slight_smile:

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
3 Likes

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:

  1. 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?
  2. 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 :slight_smile:

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.

Hi all, this is my version with 230V motors: ESPHome 6 shutters controller

@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 :wink:

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
1 Like

Uploaded the STL’s here.
Disclaimer from previous post still applies, I would recommend designing this yourself for a good fit.

2 Likes