Motor on a roller blind - ESPHome version?

I just want so write that if you need more torque its really easy to use 2 uln boards and 2 motors on one blind just connect all cabels but switch order for one uln. I have also had success of two 48byj28 on one A4988 stepper driver.

Anyone managed to get acceleration to work with the ULN board? no matter what I write, it desn’t seem to do acceleration/deacceleration.

Finally got around to test this a bit more.

Acceleration and deceleration is non functioning :frowning:
Saving position is non-existant (stopping the cover at sat 50% and then opening it again will make it go further than 0) :frowning:

That’s 2 essential functions for me, which is missing.

Anyone have an idea on how to get these 2 thing working with ULN?

Position not saving would be caused by your code (or simply not implemented). So no way to answer that if you don’t post it…

Currently this is what I have:

substitutions:
  devicename: cover_livingroom_window
  upper_devicename: Stue Vindue
  fallback: LC
  platform: ESP8266
  board: nodemcuv2
  ip: 10.254.254.50
  gateway: 10.254.254.1
  subnet: 255.255.255.0

<<: !include .common.yaml

# in Home Assistant 
api:
  services:
    - service: control_stepper
      variables:
        target: int
      then:
        - stepper.set_target:
            id: my_stepper
            target: !lambda 'return target;'

web_server:
  port: 80
  
# physical connection
stepper:
  - platform: uln2003
    id: my_stepper
    pin_a: D1
    pin_b: D2
    pin_c: D3
    pin_d: D7
    max_speed: 650 steps/s
    acceleration: 100
    deceleration: 100
    sleep_when_done: true
    
# items for Home Assistant 
cover:
  - platform: template
    name: "$upper_devicename"
    id: $devicename

    open_action:
      - stepper.report_position:
          id: my_stepper
          position: !lambda return id(my_stepper).current_position;
      - stepper.set_target:
          id: my_stepper
          target: !lambda return 11000 - id(my_stepper).current_position;

    close_action:
      - stepper.report_position:
          id: my_stepper
          position: !lambda return id(my_stepper).current_position;
      - stepper.set_target:
          id: my_stepper
          target: !lambda return -11000 + id(my_stepper).current_position;

    stop_action:
      - stepper.set_target:
          id: my_stepper
          target: !lambda return id(my_stepper).current_position;      

    optimistic: true
    has_position: true

# for manual adjustment of the initial setting position
switch:
  - platform: template
    name: "Step minus"
    turn_on_action:
      - stepper.report_position:
          id: my_stepper
          position: 0
      - stepper.set_target:
          id: my_stepper
          target: 200
  - platform: template
    name: "Step plus"
    turn_on_action:
      - stepper.report_position:
          id: my_stepper
          position: 0
      - stepper.set_target:
          id: my_stepper
          target: -200

That’s a weird open and close action :stuck_out_tongue:
What’s your min and max value? So what stepper position would be completely open and what position would be completely closed?

Let’s say your current position is 0. If you open it, it would go to 11000; if you close it, it would go to -11000.
If your current position is 5000 and you open it, it would go to 6000; if you close it, it would go to -6000.

Wouldn’t it be better to work with fixed values in your open and close action (the min and max I asked about)? And report the position as 0 after moving it up or down a bit in the adjustment block. Cause now you’re reporting it as 0 and then moving it, but your stepper would stay at 200 or -200…

Well min (open) is 0
Closed is yet to be determined, as I have not had it running succesfull yet (missing the current position, so stopping at 5000 would make it go to -6000 or 16000, depending on the next action would be open or close, rather than 0 or 11000)

Then start walking before you try to run.

Figure out your max position. Start at 0 and find the close position (easiest way I found is just to put the blind in the open position, turn on the esp & use the control_stepper service from HA). Strip unneeded code for now and add it 1 block/functionality at a time and get that block working like you want before adding anything new.

Then and only then can you look at the code and say if it’s working or not… Cause with this code it’s 100% normal it’ll go “further than 0” as you said.

Hi there.

Just read through this entotr post and figure your config is definately what I need to go with. Just about to make my purchase but I’m not sure how I can make/buy a planetary gearbox like you have in your project?

Could you let me know where you got it?.

Edit. I didn’t read all the posts so I just found your stl files. 3d printer is my issue now. Alas I’ll keep looking.

Thanks in advance.

Paul.

thanks for sharing
im having a problem when validating your code through esphome addon
im getting this error

[position_action] is an invalid option for [cover.template]. Did you mean [stop_action], [tilt_action], [open_action]?** position_action:** `

Hi! You have to have the 1.15-dev version of ESPHome, if you want to use the position_action command.

Thanks that solved the problem

anybody could explain how to use this from hassio please

In dev tools/service you could use:
cover.set_cover_position for the entity created by esp integration.
So it’s available like any other service (webui/automations/etc.)

1 Like

could you please share a picture im quite noob to hassio

im getting this error when trying to add service

Failed to call service esphome/cortina_control_stepper. required key not provided @ data[‘target’]

There’s a magic button in dev page (fill with example) beside the service call.
Indeed if you not set target how to you want your curtains to know where to go.

Hello guys!
First of all sorry for my English… :wink:
Finally I built a code what I like (some parts are “stolen” from here and there :slight_smile:), and I’d like to share with you guys, someone might like it…
So, I have two shades in my living room, both of them are 120cm wide and 180cm drop. The system can homing itself. Will do this on boot, and 2 times per week (Mondays and Thursdays) just to fix the dropped steps. The homing is done by reed switches, and magnets at the end of the weight rods.


Sorry about the wires, they are not tidied yet.
The position report is working as well with the updating period of 5 secs.
shades
I’m using 28BYJ-48 12V steppers converted to bipolar to have the sufficient torque with A4988 drivers.
There is no button control yet, but it’s in my future plan, at the moment they are controlled and automated by HA.
The code was shrinked to one shade just to save some space…
I hope this post was useful for some of you :blush:

esphome:
  name: livingroom_shade
  platform: ESP32
  board: esp-wrover-kit
  on_boot:
    priority: -10
    then:
      - script.execute: homing2

wifi:
  ssid: !secret ssid
  password: !secret wifi_pass
  manual_ip:
    static_ip: 192.168.1.65
    gateway: 192.168.1.1
    subnet: 255.255.255.0

  ap:
    ssid: "Livingroom Shade"
    password: !secret wifi_pass

captive_portal:

web_server:
  port: 80

logger:

ota:

api:

sun:
  latitude: !secret lat
  longitude: !secret long

time:
  - platform: sntp
    timezone: !secret timezone
    id: time1
    on_time:
       - seconds: 0
         minutes: 0
         hours: 10
         days_of_week: MON,THU
         then:
           - script.execute: homing2

sensor:
  - platform: uptime
    name: Nappali roló node uptime

switch:
  - platform: restart
    name: "Nappali roló node újraindítás"

binary_sensor:
  - platform: gpio
    pin:
      number: GPIO4
      mode: INPUT_PULLUP
      inverted: True
    name: "Nappali sötétítő végállás - jobb"
    id: endstop2

script:
  - id: homing2
    then:
      - logger.log: "Jobb roló pozícionálás"
      - stepper.set_speed:
          id: stepper2
          speed:  100 steps/s
      - while:
          condition:
            binary_sensor.is_off: endstop2
          then:
            - stepper.set_target:
                id: stepper2
                target: -100
            - delay: 10ms
            - stepper.report_position:
                id: stepper2
                position: 1
      - lambda: 'id(calibrated2) = 1;'
      - logger.log: "Jobb roló pozícionálva"

globals:
  - id: stepper2_steps
    type: int
    initial_value: '77000'
  - id: calibrated2
    type: int
    restore_value: no
    initial_value: '0'

cover:
  - platform: template
    name: "Nappali sötétitő - jobb"
    id: nappali_rolo_jobb
    open_action:
      - stepper.set_speed:
          id: stepper2
          speed:  300 steps/s
      - stepper.set_target:
          id: stepper2
          target: 0
      - while:
          condition:
            lambda: |-
              return id(nappali_rolo_jobb).position != 1;
          then:
            - cover.template.publish:
                id: nappali_rolo_jobb
                current_operation: !lambda |-
                    return COVER_OPERATION_OPENING;
                position: !lambda 'return 1 - (float(float(id(stepper2).current_position) / float(id(stepper2_steps))));'
            - delay: 5000 ms
      - cover.template.publish:
          id: nappali_rolo_jobb
          current_operation: IDLE
          position: !lambda 'return 1;'
    close_action:
      - stepper.set_speed:
          id: stepper2
          speed:  600 steps/s
      - stepper.set_target:
          id: stepper2
          target: !lambda "return id(stepper2_steps);"
      - while:
          condition:
            lambda: |-
              return id(nappali_rolo_jobb).position != 0;
          then:
            - cover.template.publish:
                id: nappali_rolo_jobb
                current_operation: !lambda |-
                    return COVER_OPERATION_CLOSING;
                position: !lambda 'return 1 - (float(float(id(stepper2).current_position) / float(id(stepper2_steps))));'
            - delay: 5000 ms
      - cover.template.publish:
          id: nappali_rolo_jobb
          current_operation: IDLE
          position: !lambda 'return 0;'
    stop_action:
      - stepper.set_target:
          id: stepper2
          target: !lambda return id(stepper2).current_position;
      - cover.template.publish:
          id: nappali_rolo_jobb
          current_operation: IDLE
          position: !lambda 'return 1 - (float(float(id(stepper2).current_position) / float(id(stepper2_steps))));'
    position_action:
      - stepper.set_speed:
          id: stepper2
          speed: !lambda |-
             if(pos > id(nappali_rolo_jobb).position){
                    return 300;
                  } else {
                    return 600;
                  }
      - stepper.set_target:
          id: stepper2
          target: !lambda return (id(stepper2_steps) - (int(id(stepper2_steps)*pos)));
      - while:
          condition:
            lambda: |-
              return id(nappali_rolo_jobb).position != pos;
          then:
            - cover.template.publish:
                id: nappali_rolo_jobb
                current_operation: !lambda |-
                  if(pos < id(nappali_rolo_jobb).position){
                    return COVER_OPERATION_OPENING;
                  } else {
                    return COVER_OPERATION_CLOSING;
                  }
                position: !lambda 'return 1 - (float(float(id(stepper2).current_position) / float(id(stepper2_steps))));'
            - delay: 5000 ms
      - cover.template.publish:
          id: nappali_rolo_jobb
          current_operation: IDLE
          position: !lambda 'return 1 - (float(float(id(stepper2).current_position) / float(id(stepper2_steps))));'
    has_position: true
    optimistic: false
    assumed_state: true

stepper:
  - platform: a4988
    id: stepper2
    step_pin: GPIO23
    dir_pin: GPIO22
    sleep_pin: GPIO21
    max_speed: 600 steps/s
    acceleration: 300
    deceleration: 200


8 Likes

Link is expired. Do you mind upload it again?

I put it up on thingiverse, will be easier :wink: