28byj-48 stepper motor automated blinds with esphome (Youtuber: the hookup's design) . Question about my code that was copied

Can someone give me their views on my situation. Additionally, I have posted my code at the bottom of this post (I don’t fully understand it all as it was a gift from a reddit post and does seem to be solid)-- but I do have a question about it and how stepper motors etc. work using esphome in general.

My question is: Is there anything in this code that I could change to get it (the blinds) to go further in the down direction. So what is going on is that when I click open (If we call 50% in the middle and fully open in terms of letting light into the house), the blinds are going to around 65%. And then when I click close, they are going to around 15% rather than fully closed.

Do you all see anything is this code that I can change to shift that whole range down that 15%? Am I thinking about this whole thing completely wrong? Is this showing that my stepper motor is not strong enough? Can I manually (with my hands physically) shove the blinds down to fully close from the 15% and then it will go from 0 to 50?

Sorry for all the questions, I’m just not fully following if I can fix this in the code below or if this is a physical hardware issue.

esphome:
  name: "dining-room-blinds"
  platform: ESP32
  board: nodemcu-32s

  on_boot:
    - priority: -200.0
      then:
      - stepper.report_position: # Set stepper to global variable
          id: stepper_motor
          position: !lambda return id(stepper_motor_global);
      - stepper.set_target: # Set stepper to global variable
          id: stepper_motor
          target: !lambda return id(stepper_motor_global);
      - if: # If blind is Closed
          condition:
            - lambda: 'return id(stepper_motor_global) == 0;'
          then: # Publish state etc.
            - cover.template.publish:
                id: dining_room_blinds
                state: CLOSED
                current_operation: IDLE
      - if: # If blind is Open
          condition:
            - lambda: 'return id(stepper_motor_global) == id(endstop);'
          then: # Publish state etc.
            - cover.template.publish:
                id: dining_room_blinds
                state: OPEN
                current_operation: IDLE
      - if: # If blind is Neither
          condition:
            - lambda: 'return (id(stepper_motor_global) != 0) && (id(stepper_motor_global) != id(endstop));'
          then: #  # Publish state etc.
            - cover.template.publish:
                id: dining_room_blinds
                position: !lambda 'return (float(float(id(stepper_motor).current_position) / float(id(endstop))));' 
                current_operation: IDLE
# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "NkblotNz0QL9TwPbE1tGMAcayC41bZqSRavwCtduSP4="
  services:
    - service: control_stepper
      variables:
        target: int
      then:
        - stepper.set_target:
            id: stepper_motor
            target: !lambda 'return target;'

ota:
  password: "1c32e35ea8e90d369b8feb7f8b204aef"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  fast_connect: true

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "DR-Blinds Fallback Hotspot"
    password: "Fhm0gqd5qfc3"

captive_portal:

web_server:
  port: 80
###################################################################
################################################################### STEPPER CHANGE (ENDSTOP)
###################################################################
globals:
  - id: stepper_motor_global # Integer for storing the stepper position in case of reboot
    type: int
    restore_value: True
    initial_value: '0'

  - id: openclosed # Boolean to store OPEN/CLOSED state
    type: bool
    restore_value: True
    initial_value: '0'

  - id: endstop # Variable for storing ENDSTOP (how far to move stepper)
    type: int
    restore_value: True
    initial_value: '750'   # this is the max value # this is the max value

stepper:
  - platform: a4988
    id: stepper_motor
    step_pin: GPIO2
    dir_pin: 
      number: GPIO4
      inverted: true   
    sleep_pin: 
      number: GPIO5
      inverted: true  # inverted since using enable pin
    max_speed: 250
###################################################################
################################################################### STEPPER CHANGE (TARGET)
###################################################################
cover:
  - platform: template
    name: Dining Room Blinds
    id: dining_room_blinds
    open_action:
      then:
        - logger.log: "Opening"
        - stepper.set_target: 
            id: stepper_motor
            target: 750
        - while:
            condition:
              lambda: 'return id(stepper_motor).current_position < id(endstop);'
            then:
              - cover.template.publish:
                  id: dining_room_blinds
                  position: !lambda 'return (float(float(id(stepper_motor).current_position) / float(id(endstop))));' 
                  current_operation: OPENING
              - delay: 1000 ms
        - globals.set: # Set global to current position
            id: stepper_motor_global
            value: !lambda return id(stepper_motor).current_position; 
        - globals.set: # Set toggle to OPEN (No need for 'optimistic mode')
            id: openclosed
            value: '1'
        - cover.template.publish:
            id: dining_room_blinds
            state: OPEN 
            current_operation: IDLE
    close_action:
      then:
        - logger.log: "Closing"
        - stepper.set_target: # Send stepper to 0
            id: stepper_motor
            target: '0'
        - while:
            condition:
              lambda: 'return id(stepper_motor).current_position > 0;'
            then:
              - cover.template.publish:
                  id: dining_room_blinds
                  position: !lambda 'return (float(float(id(stepper_motor).current_position) / float(id(endstop))));' 
                  current_operation: CLOSING
              - delay: 1000 ms
        - globals.set: # Set global to current position
            id: stepper_motor_global
            value: !lambda return id(stepper_motor).current_position; 
        - globals.set: # Set toggle to CLOSED (No need for 'optimistic mode')
            id: openclosed
            value: '0'
        - cover.template.publish:
            id: dining_room_blinds
            state: CLOSED
            current_operation: IDLE
    position_action:
      then:
        - stepper.set_target:
            id: stepper_motor
            target: !lambda return int(id(endstop) * pos);
        - while:
            condition:
              lambda: 'return id(stepper_motor).current_position != int(id(endstop) * pos);'
            then:
              - cover.template.publish:
                  id: dining_room_blinds
                  position: !lambda 'return (float(float(id(stepper_motor).current_position) / float(id(endstop))));' 
              - delay: 1000 ms
        - globals.set: # Set global to current position
            id: stepper_motor_global
            value: !lambda return id(stepper_motor).current_position; 
        - cover.template.publish:
            id: dining_room_blinds
            position: !lambda 'return (float(float(id(stepper_motor).current_position) / float(id(endstop))));' 
            current_operation: IDLE
    stop_action:
      then:
        - stepper.set_target:
            id: stepper_motor
            target: !lambda return id(stepper_motor).current_position;
        - globals.set: # Set global to current position
            id: stepper_motor_global
            value: !lambda return id(stepper_motor).current_position;
        - cover.template.publish:
            id: dining_room_blinds
            position: !lambda 'return (float(float(id(stepper_motor).current_position) / float(id(endstop))));' 
            current_operation: IDLE
    has_position: true
    device_class: blind

###################################################################
################################################################### STEPPER CHANGE (TARGET)
###################################################################

switch:
  - platform: template
    name: Reset Dining Room Blinds
    id: reset
    turn_on_action:
      - stepper.set_target:
          id: stepper_motor
          target: '1500'
      - wait_until: 
          lambda: 'return id(stepper_motor).current_position == 1500;'
      - delay: 1s
      - stepper.set_target:
          id: stepper_motor
          target: '0'
      - globals.set: # Set global to current position
          id: stepper_motor_global
          value: !lambda return id(stepper_motor).current_position; 
      - globals.set: # Set toggle to CLOSED (No need for 'optimistic mode')
          id: openclosed
          value: '0'
      - cover.template.publish:
          id: dining_room_blinds
          state: CLOSED
          current_operation: IDLE
      - switch.turn_off: reset
  - platform: restart
    name: "Dining Room Blinds Reboot"
    
###################################################################
###################################################################
###################################################################

# Text sensors with general information.
text_sensor:
  # Expose WiFi information as sensors.
  - platform: wifi_info
    ip_address:
      name: Dining Room Blinds IP
    ssid:
      name: Dining Room Blinds SSID

# Sensors with general information.
sensor:
  # WiFi Signal sensor.
  - platform: wifi_signal
    name: Dining Room Blinds WiFi Signal
    update_interval: 60s
    

I think target: sets where the stepper ends up.

@nickrout Thank you for this response. I may have to post this one over on the arduino forum. I don’t think there is a ton of interest in the hardware side of things over here. I don’t really want to because I would like to keep the knowledge over here but we shall see. What are your thoughts on the below

I pretty much have this working now in terms of it/ they will close fully (I have made 2 now). I am using the slider number input helper now also.–. code updated above in first post

One issue was that I had a bad gear in one of the stepper motors. It was clicking strangely and I had a feeling that was going on. The code above was found at the link at the end of this post and the only thing I added was the input helper so that I could control the rotation more granularly to figure out if I had a gear broke etc. (it told me what I needed to know luckily).

Currently I have 2 of these built now. (One with PCB (printed circuit board) and one kind of frankensteined together using standard wire/ jumpers)

The issue I am having now is that they are both in the fully closed position but one has a stepper motor position in the slider of -197 and the other has a stepper motor postion of -422. (see below)

So I’m essentially now trying to figure out how to standardize the positions at this point (they are the same motor and same blind so I’m fairly certain, this is a problem that can be solved with some slick idea, I just don’t know what the idea is)

I’m noticing in the above code (identical to linked code below) there is a “reset dining room blinds” switch—> RESET in original code. It looks like it takes the windows through a full cycle (fully open to fully closed based on the positions of 0 which is fully closed in the down direction and 1500 which is fully closed in the up postion so 750 is at mid and lets the most light in. ----> keep these values in mind with the screenshow above which is my “fully closed down”. Maybe someone smarter than me can help me correct whatever is going on.

The thing I’m concerned about is that if we overtravel them too much and they see a bunch of resistance, will it break a gear inside of the motor? I assume the answer is yes so I feel like its a balance of taking them on a reset to the point of where they begin to see a little resistance to get them both at the 0 position at the bottom. I feel like this only has to be done once and since this code seems to store the stepper position, the only time they would get out of sync was if they were manually messed with or the motor drifted somehow.

is this diagram with dvr8825 but code is a4988 true and working?

I recommend using GitHub - tronikos/esphome-blinds
I rewrote the code posted on reddit to make it a lot simpler (~100 lines of code instead of over 200 lines) and easier to use as a package.

1 Like

thanks, i have some question :

  1. is it possible use 28byj-48 stepper 12v for more power? (how i must made change on drv8825)
  2. how can i define specifice time to open or close automaticly (like alarm)?
  3. what is the metric for this two : stepper_max_speed: ‘250’ stepper_endstop: ‘650’ how can i have more power and speed ?