Measuring the time with internal clock

Hi,
I’d like to measure the time (in seconds) between two rising edges on one of the GPIOs.
Theoretically, it’s simple. I check the “timestamp” on the first edge and subtract it from the “timestamp” on the next one.
But there’s a catch… This is a battery-operated device so I need to be in Deep Sleep mode for as long as possible. So after each wake-up (via GPIO), the ESP32 chip must connect to WiFi to download data from Home Assistant or SNTP, and only then can I read the “timestamp”.

And it is the time of connecting to wifi that is the most variable factor. The other thing is that it doesn’t work locally at all. It must have internet access…

esphome:
  name: esp32-deep-sleep-test

  on_boot:
    then:
      - lambda: |-
          auto time = id(hassio_time).utcnow();

          if(id(flag) == 1)
          {
            id(flag) = 0;
            id(timeON) = time.timestamp;

            id(time_between) = (id(timeON) - id(timeOFF));
          }
          else
          {
            id(flag) = 1;
            id(timeOFF) = time.timestamp;

            id(time_between) = (id(timeOFF) - id(timeON));
          }

          ESP_LOGD("custom", "Time: %d s", id(time_between));
      - delay: 3s  
      - sensor.template.publish:
          id: deep_sleep_sensor_test
          state: !lambda 'return id(time_between);'          
      - delay: 3s  
      - switch.template.publish:
          id: sw1
          state: !lambda 'return true;'


esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "xxx"

ota:
  password: "xxx"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  fast_connect: true

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esp32-Deep-Sleep-Test"
    password: "zbmUTpyTzxXS"

captive_portal:

globals:
  - id: timeON
    type: int 
    restore_value: yes
    initial_value: '0'
  - id: timeOFF
    type: int 
    restore_value: yes
    initial_value: '0'
  - id: flag
    type: int
    restore_value: yes
    initial_value: '1'
  - id: time_between
    type: int
    restore_value: yes
    initial_value: '0'

    
time:
  - platform: homeassistant
    id: hassio_time

binary_sensor:
  - platform: gpio
    pin: 
      number: GPIO0
      inverted: True
    name: "deep_sleep_binary_sensor"

sensor:
  - platform: template
    name: "Deep Sleep Sensor test"
    id: deep_sleep_sensor_test      
    update_interval: never

switch:
  - platform: template
    name: "sw1"
    optimistic: true
    id: sw1

  - platform: template
    name: "Enter Deep Sleep"
    optimistic: true
    on_turn_off:
      then:
        - delay: 1s
        - deep_sleep.enter:
            id: deep_sleep_1

deep_sleep:
  run_duration: 24h
  sleep_duration: 24h
  wakeup_pin: GPIO0
  wakeup_pin_mode: INVERT_WAKEUP
  id: deep_sleep_1

Is it possible to use the internal clock instead? After all, I can rigidly set the run and sleep duration. So the clock must be running during Deep Sleep. Is it possible to use it to read how much time has elapsed between successive ESP wake-ups?

Thanks in advance for any hint :slight_smile:

Did you try millis() in the lambda for the timestamp? I don’t know how deep sleep would impact it’s time keeping but would be worth a shot.

ESP_LOGD("test", "Millis():  %d", millis() );

Ok, it’s been a month already. I’ve been trying to tackle this problem on and off, but I still can’t seem to figure it out. I feel like I’m going around in circles. Let me try to better describe the essence of the problem.

I want to precisely measure the time between consecutive wake-ups of ESP. I tried two approaches:

  1. Right after waking up, I check the timestamp and subtract it from the previous one, which I saved as a global variable. It kind of works, but it’s far from any “precision”. As a test, I toggle a pin from the external uC, which should wake up the ESP exactly every 60 seconds. And my results vary by ± 15s… I assume the problem is the time needed to establish a connection, initialize all peripherals, etc. The code looks like this:
esphome:
  name: esp32-deep-sleep-test

  on_boot:
    then:
      - lambda: |-
          auto time = id(hassio_time).utcnow();

          if(id(flag) == 1)
          {
            id(flag) = 0;
            id(timeON) = time.timestamp;

            id(time_between) = (id(timeON) - id(timeOFF));
          }
          else
          {
            id(flag) = 1;
            id(timeOFF) = time.timestamp;

            id(time_between) = (id(timeOFF) - id(timeON));
          }

          ESP_LOGD("custom", "Czas pomiędzy tickami: %d s", id(time_between));
      - sensor.template.publish:
          id: deep_sleep_sensor_test
          state: !lambda 'return id(time_between);'          
      - switch.template.publish:
          id: rain_sensor_test_3
          state: !lambda 'return true;'


esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "XXX"

ota:
  password: "XXX"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  fast_connect: true

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esp32-Deep-Sleep-Test"
    password: "zbmUTpyTzxXS"

captive_portal:

globals:
  - id: timeON
    type: int 
    restore_value: yes
    initial_value: '0'
  - id: timeOFF
    type: int 
    restore_value: yes
    initial_value: '0'
  - id: flag
    type: int
    restore_value: yes
    initial_value: '1'
  - id: time_between
    type: int
    restore_value: yes
    initial_value: '0'

    
time:
  - platform: homeassistant
    id: hassio_time

binary_sensor:
  - platform: gpio
    pin: 
      number: GPIO0
      inverted: True
    name: "deep_sleep_binary_sensor"

sensor:
  - platform: template
    name: "Deep Sleep Sensor test"
    id: deep_sleep_sensor_test      
    update_interval: never

switch:
  - platform: template
    name: "rain sensor test 3"
    optimistic: true
    id: rain_sensor_test_3

  - platform: template
    name: "Enter Deep Sleep test"
    optimistic: true
    on_turn_off:
      then:
        - delay: 1s
        - deep_sleep.enter:
            id: deep_sleep_1

deep_sleep:
  run_duration: 24h
  sleep_duration: 24h
  wakeup_pin: GPIO0
  wakeup_pin_mode: INVERT_WAKEUP
  id: deep_sleep_1

  1. I created a binary sensor: ‘status’, and in HA, I check for any large deviations between consecutive “connected” states. As you can imagine, the result is very similar… ± several seconds.

Is there a better way to do this? I mean, there must be some sort of timer running during deep-sleep. In other cases, you can set a timer for when the ESP wakes up on its own. Can’t we use that to calculate the time? I feel like that would be a much better solution, completely independent of WiFi connection time.

If you have any ideas, I would be very grateful :slight_smile: