Witam, to nie 100% temat HA, ale: wymyśliłem sobie, że zbuduję pewnego rodzaju obrotowy nalewak do trunków 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:
- wykonaj obrót o 4000kroków
- 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 - Gdy ponownie wykryje przeszkodę <10 wróć do pkt2
- 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
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;'