Best practices? Relay on for certain number of pulses? (Drive revolutions on cat food dispenser)

What would be the best practice? I have a cat food dispenser (an excellent one too, stand-alone, dumb clock based) that has a cam and microswitch on the output shaft of the motor. So it’s actually closed-loop. An average feeding time might be 10 seconds and 20 pulses - I could (and do) use a timer, but that’s sloppy. the Pulse counter component comes to mind, although it doesn’t seem entirely appropriate, and I realize I need to “close the loop” on the ESP itself for proper “safe” operation (nothing actually dangerous about a mountain of cat food on the floor however)

Logically, when the feeder is triggered ON, a variable will come in from Home Assistant, the relay will trigger ON, and on the rising/falling edge of the switch, a variable will decrement until we reach zero, and then the relay will turn off.

I realize there are probably 20 bad ways to do this, so what’s the right way?

Thanks!

If I understand correctly you want to quickly turn on and off a relay/switch? There is a repeat action, I use it in a script to pulse a waterpump. I call the script with a button. I bring in 2 input numbers from HA.

I use 2 because the delay of the on/off is different than how long it waits to start the next loop, you may not need to use it. You will need a input number(count) if you want to be able to adjust the times it loops.

script:
  - id: multi
    mode: single
    then:
    - repeat:
        count: !lambda 'return id(count);'
        then:
          - switch.turn_on: relay
          - delay: !lambda 'return id(pump_duration);'
          - switch.turn_off: relay
          - delay: !lambda 'return id(inter_delay);'

Thank you, but I’m thinking of something different. I don’t want to pulse an output. I want to have an output turn off after a certain number if INPUT pulses.

My situation is that I have a nice slow motor with a cam, which actuates a microswitch a few times every revolution. In this way, the controlling circuit can track the number of rotations that the motor makes, and in my case, turn it off after a certain number of rotations - say, 20 falling edges on the micro switch input. This switch provides feedback as to how many rotations the motor has been made. The sensor is not an encoder, but more like an odometer. It just measures how far, ignoring the direction, based on the number of pulses.

The setup is similar in principal to this:


Mine is all black and hidden, and difficult to photograph, so hence this easy to understand image.

On an Arduino, I’d reset a variable to my target, activate the relay, probably just poll the switch input (no need for interrupts on something that operates at 2 hz) , then decrement the variable on a transition from one state to the other, until zero, at which point the relay will turn off, and we’re done.

I thought initially that a “cover” component might be excellent, but covers don’t work with odometer style sensors.

The pulse counter component seems more like counting the pulses coming out of a utility meter or some other long term, accumulative measurement.

Have I done a decent job explaining my question?
Thank you!

Yes, I believe so. There are 2 options for creating a variable, global or a number component for this case. I used the number component in my example. Under the micro switch sensor component using the appropriate trigger

    on_value: // adj according to component docs
      - if:
          condition:
            switch.is_on: your_switch_id
          then:
            - if:
                condition:
                  lambda: 'return id(my_number).state < 20;'
                then:
                  - number.increment: my_number
                else:
                  - switch.turn_off: your_switch_id
                  - number.set:
                      id: my_number
                      value: 0

edit: In the lambda condition you could use another number so the amount of turns can be adjusted

lambda: 'return id(my_number).state < return id(my_other_number).state;'