ESP32 z włączonym Wi-Fi pobiera kilkadziesiąt miliamperów, a podczas krótkich serii nadawania znacznie więcej. Karta katalogowa Espressifa podaje 240 mA przy nadawaniu w standardzie 802.11b z mocą +19,5 dBm. Przy takim poborze akumulator szybko się rozładuje. W trybie głębokiego uśpienia („deep sleep”) ten sam układ potrzebuje około 10 µA (działa wtedy tylko zegar RTC i pamięć RTC). Czujnik, który się budzi, wysyła odczyt i od razu zasypia, prawie cały czas spędza więc w najtańszym stanie.

W ESPHome głębokie uśpienie to jeden komponent. Więcej pracy wymaga wszystko dookoła: trzeba skrócić czas czuwania, zdążyć wysłać odczyty przed zaśnięciem, zachować możliwość aktualizacji oprogramowania i dobrać sprzęt, który nie zmarnuje oszczędności.

Co się dzieje w czasie głębokiego uśpienia

W głębokim uśpieniu zasilanie mają tylko pamięć RTC i peryferia RTC. Wi-Fi, Bluetooth i główny procesor są wyłączone. Wybudzenie przypomina ponowne uruchomienie: układ startuje oprogramowanie od początku, znowu łączy się z Wi-Fi i od nowa konfiguruje wszystkie komponenty.

Wynikają z tego dwie rzeczy:

  • Uśpione urządzenie jest nieosiągalne. Dokumentacja ESPHome mówi wprost, że śpiący węzeł nic nie robi i nie odpowiada na ruch sieciowy, także na aktualizacje przez sieć (OTA).
  • Każde wybudzenie to nowe połączenie z Wi-Fi. Zwykle najwięcej energii kosztuje właśnie łączenie się z siecią, a nie pomiar, więc większość ustawień opisanych niżej służy skróceniu tego etapu.

ESP32 może się obudzić po upływie ustawionego czasu, po zmianie stanu pinu obsługującego RTC (według listy w ESPHome są to GPIO0, 2, 4, 12-15, 25-27, 32 i 39) albo po dotyku. ESP8266 budzi się tylko po czasie i tylko wtedy, gdy GPIO16 jest połączony z pinem RST.

Sprzęt: płytka znaczy więcej niż sam układ

Wartość 10 µA dotyczy samego układu. Typowa płytka prototypowa ma do tego konwerter USB-UART, diodę zasilania i stabilizator napięcia, a każdy z tych elementów pobiera prąd także wtedy, gdy ESP32 śpi. Stabilizator AMS1117-3.3, częsty na tanich płytkach, ma według karty katalogowej typowy prąd spoczynkowy 5 mA. To pięćset razy więcej, niż potrzebuje uśpiony układ.

Jeśli zależy ci na długiej pracy na akumulatorze:

  • Wybierz płytkę zaprojektowaną do zasilania bateryjnego albo goły moduł z własnym układem zasilania. Zanim uwierzysz w jakąkolwiek liczbę, także tę ze strony produktu, zmierz prąd w uśpieniu multimetrem włączonym szeregowo z akumulatorem.
  • Dobierz stabilizator pod kątem prądu spoczynkowego i prądu szczytowego. W spoczynku powinien pobierać mikroampery, a mimo to wytrzymać szczyty przy nadawaniu. Espressif zaleca zasilanie 3,3 V o wydajności co najmniej 500 mA.
  • Pilnuj zakresu napięć. ESP32 pracuje przy napięciu od 2,3 do 3,6 V. W pełni naładowane ogniwo litowo-jonowe ma około 4,2 V, więc nie można go podłączyć bezpośrednio do pinu 3,3 V. Liczy się też spadek napięcia na stabilizatorze: dla AMS1117 karta katalogowa podaje typowo 1,1 V przy 1 A, a rozładowujące się ogniwo szybko traci taki zapas.
  • Płytki z ESP8266 i układem USB (na przykład D1 mini) mogą się nie budzić przy zasilaniu przez USB, bo układ USB steruje też linią RST. ESPHome radzi zasilić taką płytkę z osobnego źródła 3,3 V.

Pomiar napięcia akumulatora

Żeby widzieć stan akumulatora w Home Assistancie, podłącz akumulator przez dzielnik napięcia do pinu przetwornika ADC. W podstawowym ESP32 wybierz pin z przetwornika ADC1 (GPIO32-39). Dokumentacja Espressifa zaznacza, że z ADC2 korzysta też sterownik Wi-Fi, a Wi-Fi pracuje właśnie wtedy, gdy czujnik się budzi.

Dwa jednakowe rezystory dzielą napięcie na pół, więc z 4,2 V robi się 2,1 V. Przy domyślnym tłumieniu 0db przetwornik ADC w ESP32 mierzy w ESPHome tylko do około 1,1 V, dlatego ustaw attenuation: 12db. W testach ESPHome użyteczny zakres sięgał około 3,12 V, więc 2,1 V mieści się w nim bez problemu.

Pamiętaj, że dzielnik cały czas rozładowuje akumulator. Dwa rezystory po 100 kΩ to razem 200 kΩ, więc przy 4,2 V płynie przez nie 21 µA, czyli dwa razy więcej, niż pobiera uśpiony układ. Większe rezystory zmniejszą tę stratę, ale przy źródle o dużej impedancji odczyty ADC są mniej stabilne. Zanim zamkniesz płytkę w obudowie, sprawdź, jakie wartości faktycznie odczytuje ESP32.

Konfiguracja

Przykład dotyczy ESP32 z czujnikiem temperatury i wilgotności SHT4x na magistrali I²C. Czujniki nie mierzą tu według własnego harmonogramu. Urządzenie czeka, aż połączy się Home Assistant, robi po jednym odczycie z każdego czujnika, daje wartościom chwilę na dotarcie do Home Assistanta i zasypia na dziesięć minut.

esphome:
  name: garden-sensor
  on_boot:
    priority: -100
    then:
      - wait_until:
          condition: api.connected
          timeout: 20s
      - component.update: climate
      - component.update: battery_voltage
      - delay: 2s
      - if:
          condition:
            binary_sensor.is_off: ota_mode
          then:
            - deep_sleep.enter: deep_sleep_1

esp32:
  board: esp32dev

logger:

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  fast_connect:
    enabled: true
    storage: rtc
  manual_ip:
    static_ip: 192.168.1.60
    gateway: 192.168.1.1
    subnet: 255.255.255.0

api:
  encryption:
    key: !secret api_encryption_key

ota:
  platform: esphome

deep_sleep:
  id: deep_sleep_1
  run_duration: 30s
  sleep_duration: 10min

i2c:
  sda: GPIO21
  scl: GPIO22

sensor:
  - platform: sht4x
    id: climate
    update_interval: never
    temperature:
      name: Temperature
    humidity:
      name: Humidity

  - platform: adc
    id: battery_voltage
    name: Battery voltage
    pin: GPIO35
    attenuation: 12db
    samples: 8
    update_interval: never
    filters:
      - multiply: 2.0

binary_sensor:
  - platform: homeassistant
    id: ota_mode
    entity_id: input_boolean.garden_sensor_ota_mode
    on_state:
      - if:
          condition:
            lambda: 'return x;'
          then:
            - deep_sleep.prevent: deep_sleep_1
          else:
            - deep_sleep.allow: deep_sleep_1

Na co zwrócić uwagę:

  • on_boot z priority: -100. Według ESPHome przy tym priorytecie prawie wszystko jest już zainicjowane, więc gdy skrypt startuje, Wi-Fi i API są już skonfigurowane.
  • wait_until: api.connected z limitem czasu. Nie ma sensu mierzyć, zanim Home Assistant zacznie odbierać dane. Dzięki limitowi 20 s urządzenie bez połączenia nie czeka w nieskończoność.
  • update_interval: never i component.update. Czujniki mierzą tylko na polecenie skryptu, raz na wybudzenie i dokładnie wtedy, gdy wynik da się wysłać.
  • run_duration: 30s jako zabezpieczenie. Jeśli coś się zawiesi, węzeł i tak zaśnie po 30 sekundach i nie rozładuje akumulatora.
  • fast_connect i manual_ip. Oba ustawienia skracają łączenie. fast_connect pomija pełne skanowanie i od razu łączy się z ostatnim znanym punktem dostępowym. Z storage: rtc zapisuje jego BSSID i kanał w pamięci RTC, która przetrwa głębokie uśpienie, a pamięć flash się nie zużywa. Przy stałym adresie IP urządzenie nie musi czekać na DHCP. Dokumentacja Wi-Fi w ESPHome zaleca go, bo potrafi wyraźnie skrócić czas łączenia. Adresy dopasuj do własnej sieci.
  • GPIO21 i GPIO22 to tylko przykład. Do I²C nadadzą się dowolne wolne piny.

Jak aktualizować uśpiony czujnik

Węzeł, który co dziesięć minut czuwa przez kilka sekund, trudno złapać do aktualizacji przez sieć. Czujnik binarny ota_mode z przykładu rozwiązuje to z poziomu Home Assistanta:

  1. Utwórz pomocnika typu przełącznik w menu Ustawienia > Urządzenia oraz usługi > Pomocnicy (Settings > Devices & services > Helpers) i nadaj mu identyfikator encji input_boolean.garden_sensor_ota_mode.
  2. Przed aktualizacją włącz ten przełącznik i poczekaj na najbliższe wybudzenie. Urządzenie odczyta jego stan z Home Assistanta i wywoła deep_sleep.prevent, a warunek if w on_boot nie pozwoli mu zasnąć.
  3. Wgraj nowe oprogramowanie. Potem wyłącz przełącznik: wykona się deep_sleep.allow i urządzenie wróci do zwykłego cyklu.

Jeśli zamiast natywnego API używasz MQTT, w dokumentacji ESPHome znajdziesz ten sam sposób oparty na zachowanej wiadomości („retained”).

Przy aktualizacjach ESP32 z platformą ESP-IDF, gdzie wycofywanie aktualizacji jest domyślnie włączone, trzeba pamiętać o jeszcze jednym. ESPHome musi potwierdzić, że nowe oprogramowanie działa, inaczej program rozruchowy przy następnym restarcie przywróci poprzednią wersję. Od ESPHome 2026.8.0 wejście w głębokie uśpienie liczy się jako udany start. We wcześniejszych wersjach urządzenie, które zasnęło przed upływem boot_is_good_after (domyślnie minuta), nigdy nie potwierdzało aktualizacji i po każdym wybudzeniu po cichu wracało do starej wersji. Jeśli musisz zostać przy starszej wersji, ustaw w sekcji safe_mode: wartość boot_is_good_after krótszą od czasu czuwania, na przykład 10s.

Co pokazuje Home Assistant, gdy czujnik śpi

Encje powinny pokazywać ostatnią wartość także w czasie uśpienia. Jeśli zamiast tego mają stan „Niedostępny” („Unavailable”), według dokumentacji ESPHome komponent deep_sleep został prawdopodobnie dodany dopiero wtedy, gdy urządzenie było już w Home Assistancie. Wystarczy usunąć urządzenie z Home Assistanta i dodać je ponownie.

Ile wytrzyma akumulator

Nie opieraj się na samej karcie katalogowej. Zmierz dwa prądy i dwa czasy: prąd w czasie czuwania i długość typowego wybudzenia (raz podejrzyj logi przez USB) oraz prąd w uśpieniu. Potem policz średnią:

średni prąd = (prąd czuwania x czas czuwania + prąd uśpienia x czas uśpienia) / długość cyklu

Czysto hipotetyczny przykład: jeśli płytka pobiera 100 mA przez 5 s i 20 µA przez pozostałe 595 s dziesięciominutowego cyklu, średnia wynosi około 0,85 mA i prawie cała pochodzi z czuwania. Podziel pojemność akumulatora przez tę średnią, a dostaniesz przybliżony czas pracy. Odejmij od niego zapas na mróz, starzenie się ogniwa i nieudane próby połączenia z Wi-Fi. Ze wzoru widać też, gdzie szukać oszczędności: krótsze wybudzenie i dłuższe sleep_duration dają dużo więcej niż walka o kilka mikroamperów w uśpieniu, o ile sama płytka nie zużywa miliamperów.

Gdy coś nie działa

  • Węzeł w ogóle się nie budzi (ESP8266). GPIO16 nie jest połączony z RST albo układ USB na płytce zakłóca linię resetu.
  • Węzeł się budzi, ale do Home Assistanta nie docierają wartości. Zasnął, zanim połączyło się API. Sprawdź w logach, ile trwa łączenie, wydłuż limit w wait_until i zostaw krótkie delay po odczytach.
  • Napięcie akumulatora wynosi 0 albo skacze. Sprawdź, czy pin należy do ADC1, czy ustawiłeś attenuation i czy filtr multiply pasuje do stosunku rezystorów w dzielniku.
  • Akumulator rozładowuje się w kilka dni, a nie miesięcy. Zmierz prąd w uśpieniu. Jeśli wychodzą miliampery, winna jest płytka (stabilizator, dioda, konwerter USB) albo dzielnik, a nie ESPHome.
  • Aktualizacja znika po następnym wybudzeniu. To opisane wyżej wycofanie aktualizacji. Zaktualizuj ESPHome albo skróć boot_is_good_after.