ESP32-H2 Supermini ext1_wakeup with simulated invert mode

Hi,

To thank the community on this forum, where I found a lot of information for my little door-opening detector project based on an ESP32-h2, I’m sharing my ESPHome code, which uses the deep_sleep ext1_wakeup (the only one available on the ESP32-h2) with a simulated INVERT_WAKEUP mode. The sensor is recognized correctly by zigbee2MQTT. Feel free to provide feedback or suggest improvements to this code.

esphome:
  name: zb-contact-esp32h2
  on_boot:
    then:
      - script.execute: flash_led
  
external_components:
  - source: github://luar123/zigbee_esphome
    components: [zigbee]

zigbee:
  id: "zb"
  components: all
  manufacturer: ESPRESSIF
  power_supply: 3
  on_join:
    then:
      - logger.log: "Joined network"

esp32:
  board: esp32-h2-devkitm-1
  toolchain: platformio
  framework:
    type: esp-idf

# Enable logging
logger:
  hardware_uart: USB_SERIAL_JTAG

# Define the output for the internal blue LED
output:
  - platform: gpio
    pin: GPIO13  # Internal Blue LED
    id: internal_led

# Define the script to flash the internal blue LED when wakeup (or boot)
script:
  - id: flash_led
    then:
      - output.turn_on: internal_led
      - delay: 330ms
      - output.turn_off: internal_led
      - delay: 230ms
      - output.turn_on: internal_led
      - delay: 330ms
      - output.turn_off: internal_led
      - delay: 230ms
      - output.turn_on: internal_led
      - delay: 330ms
      - output.turn_off: internal_led

sensor:
  - platform: internal_temperature
    name: "Temperature SoC"
    id: "temp"
    unit_of_measurement: "°C"
    filters:
      - clamp:
          min_value: 10
          max_value: 95
          ignore_out_of_range: true

# Pont diviseur (Vin-1MOhm-GPIO01-1MOhm-Gnd)
# entre la tension d'alim et le GPIO01 (rapport ~= 1:2)
  - platform: adc
    name: "Battery Voltage"
    unit_of_measurement: "V"
    device_class: voltage
    accuracy_decimals: 2
    id: "batt"
    pin: 1
    update_interval: 10s
    attenuation: 12dB
    samples: 10
    sampling_mode: max
    filters:
       - multiply: 2.0  # The voltage divider requires us to multiply by 2
       - clamp:
          min_value: 1
          max_value: 4.3
          ignore_out_of_range: true
binary_sensor:
  - platform: gpio
    device_class: window
    pin:
      number: 14
      inverted: true
      mode:
        input: true
      allow_other_uses: true
    id: button_1
    name: "Contact"
    on_state:
      then:
        - lambda: |-
            uint64_t mask = 1ULL <<  14; // MUST BE THE SAME AS THE PIN NUMBER
            if ( id(button_1).state == 0 ) { // 0 = Off, 1 = On
                deep_sleep_deepsleepcomponent_id->set_ext1_wakeup( deep_sleep::Ext1Wakeup{
                  .mask = mask,
                  .wakeup_mode = ::ESP_EXT1_WAKEUP_ANY_LOW,
                });
            } else {
                deep_sleep_deepsleepcomponent_id->set_ext1_wakeup( deep_sleep::Ext1Wakeup{
                  .mask = mask,
                  .wakeup_mode = ::ESP_EXT1_WAKEUP_ANY_HIGH,
                });
            }
            id(batt).update();
            id(temp).update();
        - logger.log: "State changed"
        - zigbee.report: zb

    on_multi_click:
      timing:
       - ON for at most 1s
       - OFF for at most 1s
       - ON for at most 1s
       - OFF for at most 1s
       - ON for at most 1s
       - OFF for at least 0.5s
      then:
         - zigbee.reset: zb
    trigger_on_initial_state: true

# Deep Sleep Component
deep_sleep:
   sleep_duration: 60min
   run_duration: 20s
   esp32_ext1_wakeup:
      pins:
         number: 14
         mode:
             input: True
         allow_other_uses: true
      mode: ANY_LOW

Thanks

I’m not familiar with H2, neither with your external component. But 20s fixed wake-time doesn’t sound efficient.

Hi Karosm, thanks for your reply. What do you mean by “doesn’t sound efficient”? It looks like this time is always enough to the esp32 to join the network and send his data, why do you think I should set this to a higher value ?

Probably the fact that it’s using Zigbee rather than the API helps.

EDIT - ignore me - you could mean that it could be shorter - yes would be more efficient too go back to sleep immediately after you have done whatever you need to do rather than stay awake for fixed period…

Yes, I meant this, but didn’t describe it sufficiently. “Efficient” for battery life.

Ok! Now I understand. I will see how I can fall in deep sleep just after data are sended. Thank you
EDIT: Hum, looks like it’s not so easy, without mqtt (ESP32-H2 has no wifi), to detect if sensor’s data have been send or not . If anybody has an idea?
EDIT2: There was a bug in the yaml file if the binary_sensor state change while esp32-h2 is running. I change the file and think it’s ok now.