ESPHome i zaprogramowanie pewnej procedury

Witam, to nie 100% temat HA, ale: wymyśliłem sobie, że zbuduję pewnego rodzaju obrotowy nalewak do trunków :slight_smile: Tak też uczyniłem, wykorzystałem Nodemcu, pompę wodną, servo-stepper, czujnik odległości i przycisk. Całość mechanicznie jest już złożona, myślałem, że w ESPhome szybko uruchomię prosty algorytm, ale cóż… proszę o pomoc (wydawało mi się to proste;) ) w nakierowaniu mądrzejsze głowy jak ustawić taki algorytm:

I. jeśli przycisk jest wciśnięty krótko raz:

  1. wykonaj obrót o 4000kroków
  2. ale gdy sensor odległości wykryje <10 (wykryje szklankę) to:
    a) zatrzymaj obrót,
    b) włącz pompkę na 2s, następnie wyłącz pompkę
    c) kontynuuj obrót i przez 50 kroków ignoruj sensor odległości
  3. Gdy ponownie wykryje przeszkodę <10 wróć do pkt2
  4. Gdy osiągnie pozycje 4000:
    a) pomiń sprawdzanie odległości,
    b) powrót do pozycji 0

Już tydzień się męczę, a chciałbym na święta wypróbować eksperyment :smiley:

EDIT:
Determinacja i lekkie olśnienie i działa jak sobie zamierzyłem
Poniżej poprawiony kod:

esphome:
  name: drink-distributor
  platform: ESP8266
  board: nodemcuv2

logger:
  level: DEBUG
  logs:
    component: ERROR
    vl53l0x: INFO
    json: ERROR
    
api:

ota:
  password: "4eca72b467a4366475a4ba03efd2400b"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  fast_connect: true
  ap:
    ssid: "Drink-Distributor"
    password: "VUhZ7QRHeiwq"

captive_portal:
    
web_server:
  port: 80

i2c:
  scl: GPIO5
  sda: GPIO4

# servo uln
stepper:
  - platform: uln2003
    id: obrot
    pin_a: GPIO0
    pin_b: GPIO2
    pin_c: GPIO15
    pin_d: GPIO13
    max_speed: 300 steps/s
    acceleration: inf
    deceleration: inf
    sleep_when_done: True

switch:
  - platform: gpio #pompa
    pin: GPIO12
    id: pump
  
sensor:
  - platform: vl53l0x
    name: "VL53L0x Distance"
    address: 0x29
    id: dist
    accuracy_decimals: 2
    update_interval: 130ms
    filters:
        - delta: 0.01 # unless dist has changed by more than 4cm
    unit_of_measurement: "m"
    #filters:
    #  - median: 
    #      window_size: 5
    #      send_every: 3
    #      send_first_at: 3
    on_value_range:
      - below: 0.08
        then: 
          if:
            condition:
              - script.is_running: powrot
            then:

            else:
              if:
                condition:
                  lambda: "if (id(obrot).current_position > 0)  { return true; } else { return false; }"
                then:
                  - script.execute: nalej

#display:
#  - platform: lcd_pcf8574
#    dimensions: 16x2
#    address: 0x27
#    id: lcd
#    lambda: |-
#      it.printf(0, 0, "Odl: %.3f cm", id(dist).state*100);
#      it.printf(0, 1, "Status: %s",  id(status).value);
#      it.print(0, 0, "Spragniony?");
#      it.print(0, 1, "Podaj szklo...");

binary_sensor:
  - platform: gpio #button1
    pin:
      number: 14
      mode: INPUT_PULLUP
      inverted: false
    filters:
      - delayed_on: 100ms
      - delayed_off: 100ms
    id: btn

    on_multi_click:
#      #Double Click
#          - OFF for at most 0.5s
#          - ON for at most 0.3s
#          - OFF for at most 0.5s
#          - ON for at least 0.2s
#        #Release
#          - OFF for at least 1.5s
#          - ON for at least 0.5s

      #Hold - uzupelnij przewody cieczą
      - timing:
          - OFF for at least 2s
        then:
          - logger.log: "Initial"
          - stepper.set_target:
              id: obrot
              target: !lambda return id(obrot).current_position;
          - switch.turn_on: pump #start nalewania
          
          - while:
              condition:
                binary_sensor.is_off: btn
              then:
                - delay: 10ms
          - switch.turn_off: pump
          - logger.log: "stop"
          - delay: 500ms #czas spoczynku przed powrotem

      #Single Click
      - timing:
          - OFF for at most 300ms
          - ON for at least 500ms
        then:
          - if:
              condition:
                lambda: "if (id(obrot).current_position > 0)  { return true; } else { return false; }"
              then: #powrot
                - script.execute: powrot
              else: #start
                - script.execute: start

script:
  - id: start
    then:
      - logger.log: "Start "
      - stepper.set_target:
          id: obrot
          target: 4000
      - delay: 500ms
      - if:
          condition:
            lambda: 'return id(dist).state*100 < 10;'
          then:
            - script.execute: nalej
      - if:
          condition:
            lambda: "if (id(obrot).current_position == 4000)  { return true; } else { return false; }"
          then:
            - script.execute: powrot
      - wait_until: 
          lambda: 'return id(obrot).current_position == 4000;'
      - script.execute: powrot

  - id: nalej
    then:
      - logger.log: "nalewanie"
      - delay: 300ms #czas zatrzymania
      - stepper.set_target:
          id: obrot
          target: !lambda return id(obrot).current_position;
      - switch.turn_on: pump #start nalewania
      - delay: 2000ms #czas nalewania
      - switch.turn_off: pump
      - delay: 1000ms #czas spoczynku przed powrotem
      - stepper.set_target:
          id: obrot
          target: 4000
      - delay: 300ms #czas ominiecia

  - id: powrot #powrot do domu
    then:
      - logger.log: "powrot"
      - switch.turn_off: pump
      - delay: 1000ms #czas spoczynku przed powrotem
      - stepper.set_target:
          id: obrot
          target: 0
      - wait_until: 
          lambda: 'return id(obrot).current_position == 0;'

Jak to nie byc polaczone z HomeAssistantem to bym napisal to w C w srodowisku Arduino. :wink:

Skusiła mnie “pozorna” prostota w dodawaniu sensorów no i OTA (mam zablokowany komputer by wgrywać po kablu).

Ale finalnie się udało ogarnąć program wg założeń w esphome (kod w poście nr1) :wink:

1 polubienie