Opis konstrukcji

Z okazji wakacyjnego wyjazdu powstała konieczność stworzenia urządzenia które zadba żeby kot który zostaje nie był głodny. Nie jest to już pierwsze podejście do tego tematu, poprzednie jednak oparte o konstrukcję ze śrubą która dozuje karmę się nie sprawdziło, ciężko było ustalić ilość sypanej karmy oraz często mechanizm ulegał zablokowaniu. Dlatego powstała konstrukcja oparta o silnik krokowy 28byj-48 przerobiony na wersję bipolarną który obraca całym pojemnikiem z przegrodami.

Przerobienie silnika wymaga zdjęcia niebieskiego kapsla który zakrywa przewody oraz przecięcia środkowej ścieżki, następnie pozbywamy się czerwonego przewodu (+5V) który jest do niej podłączony, dzięki temu uzyskujemy silnik z większym momentem obrotowym.

Pojemnik jest podzielony na 8 części, z czego jedna musi być pusta więc mamy 7 porcji karmy.

Model 3d

Kod

Przedstawiony poniżej fragment kodu yaml do wykorzystania z esphome (pominąłem startową konfigurację esp oraz połączenia)

time:
  - platform: homeassistant
    id: homeassistant_time
    timezone: Europe/Warsaw
    on_time:
      - cron: 0 0 08 * * * #cron to configure automatic run
        then: 
          - if:
              condition:
                - lambda: return id(run_container).state;
              then:
                - button.press: next_slot
stepper: #stepper motor configuration
  - platform: uln2003
    id: my_stepper
    pin_a: 4
    pin_b: 5
    pin_c: 3
    pin_d: 13
    max_speed: 200 steps/s
    sleep_when_done: true
    acceleration: inf
    deceleration: inf

globals:
   - id: container_state
     type: int
     restore_value: no
     initial_value: '8'
   - id: stepper_position
     type: int
     restore_value: no
     initial_value: '0'

number:
  - platform: template
    id: stepper_steps
    initial_value: 1024
    min_value: 1020
    max_value: 1030
    step: 1
    optimistic: true

button:
  - platform: template
    name: "Reset Container State"
    entity_category: config
    icon: 'mdi:restore'
    on_press:
    - globals.set:
        id: container_state
        value: '8'
    - sensor.template.publish:
        id: container_state_sensor
        state: !lambda return id(container_state);
  - platform: template
    name: "Next Container Slot"
    icon: 'mdi:skip-next-circle-outline'
    id: next_slot
    on_press:
      - lambda: |-
          if (id(container_state) > 0)
            id(container_state)--;          
      - sensor.template.publish:
          id: container_state_sensor
          state: !lambda return id(container_state);
      - stepper.set_target:
          id: my_stepper
          target: !lambda return id(my_stepper).current_position + id(stepper_steps).state;
  - platform: template
    id: "Clean"
    icon: 'mdi:trash-can'
    entity_category: config
    on_press:
      - stepper.set_target:
          id: my_stepper
          target: !lambda return id(my_stepper).current_position + id(stepper_steps).state * 8;
      - globals.set:
          id: container_state
          value: '0'
      - sensor.template.publish:
          id: container_state_sensor
          state: !lambda return id(container_state);

switch:
  - platform: template
    id: run_container
    icon: 'mdi:clock-star-four-points-outline'
    name: "Auto run container"
    optimistic: true

sensor:
  - platform: template
    name: "Container State"
    icon: 'mdi:counter'
    id: container_state_sensor
    lambda: |-
      return id(container_state);      
    update_interval: 300s

Filmik z działania