How to save stepper motor position and retrieve it on reboot?

How do you guys save the motor position so when the ESP reboots, it knows what position the stepper motor is at?

I have a stepper motor that rotates clockwise or counter clockwise depending on the value of a photoresistor. I’m trying to save the value of the position in the globals. But I can’t properly retrieve it.

I created two globals for the value of the steps depending on the value of the photoresistor.

  - id: current_light
    type: float
    restore_value: no
#    initial_value: '0'

  - id: previous_light
    type: float
    restore_value: yes
    initial_value: '0'

These globals I used to store the value of the photoresistor that I use to run the motor.

    on_value:
      then:
        - globals.set:
            id: current_light
            value: !lambda return id(ambient_sensor).state;
        - delay: 1s
        - if:
            condition:
              switch.is_off: auto_light_enable_script
            then:
              - if:
                  condition:
                    or:
                      - lambda: return id(current_light) - id(previous_light) > 5.0;
                      - lambda: return id(current_light) - id(previous_light) < -5.0;
                  then:
                    - lambda: id(oled).turn_on();
                    - stepper.set_target:
                        id: stepper_motor
                        target: !lambda return ((id(current_light) / 100) * id(endstop));
                    - globals.set:
                        id: previous_light
                        value: !lambda return id(current_light);
                  else:
                    - lambda: id(oled).turn_off();
                    - stepper.report_position:
                        id: stepper_motor
                        position: !lambda return ((id(previous_light) / 100) * id(endstop));

And this part is the entire automation. Here’s how it’s currently working – when the value of the resistor changes 5 levels higher or lower, the motor will turn either counter clockwise or clockwise depending on the value the photoresistor.

This works fine, but when the ESP reboots, I can’t get the motor to retrieve it’s position.

  on_boot:
    then:
    - ds1307.read_time
    - display.page.show: intro_page
    - delay: 2s
    - display.page.show: main_page
    - delay: 5s
    - globals.set:
        id: current_light
        value: !lambda return id(ambient_sensor).state;
    - stepper.report_position:
        id: stepper_motor
        position: !lambda return ((id(previous_light) / 100) * id(endstop));
    #- lambda: id(oled).turn_on();

Here’s what I added in the on_boot: But I’m doing it wrong. When it boots the motor keeps on turning nonstop, until the value of the resistor changes.

My previous code was something like this:

on_boot:
...
- stepper.set_target:
    id: stepper_motor
    target: !lambda return ((id(current_light) / 100) - (id(previous_light) / 100));

Basically the code above calculates the current light value against with the previous value and multiply it to endstop – endstop is the value of the max step of the motor.

For example. If the current value of the light is 1000 and the previous light value is 1000, result will be 0. But when the ESP reboots, the motor turns a complete 1000 steps. I can’t figure out why this is happening. Sometimes if the previous value is 750 and the current value is 1000, the motor rotates a full 1000 steps, then rotate another 250 for the result of the values. I don’t understand.

Another question – what’s the reason why the ESP reboots randomly after some time? – this is one reason why I want to retain the motor position. And also I wanna try using deep sleep with this.

Check out restore_from_flash here: ESP8266 Platform — ESPHome

I needed to store a global variable to survive reboots, and this did it for me. Also need to set the restore_value to true in the global variable declaration - see here: Automations and Templates — ESPHome

Hope that helps.