I2C bus scan after deep sleep recovery

Hello,

In order to make a device that consumes the minimum power, I needed to power the sensors by enabling a pin from the ESP32, so when I enter in deep sleep mode, the sensors stop being powered and I save a critical amount of energy. Among the different sensors, I have an I2C device, that works perfectly the first time after a reset (when I guess the instruction of setting up the I2C bus according to the pinout definition takes place).

However, after any of the recoveries of a deep sleep, the I2C device is no longer there to be read (despite the power on the sensor feeding line having been recovered). Here is my code

esphome:
  name: device    

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:

ota:
  password: *****

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

captive_portal:

i2c:
  scl: GPIO22
  sda: GPIO21
  scan: true
  id: bus_a

sensor:
  # Temperature and humidity sensor
  - platform: aht10
    i2c_id: bus_a
    address: 0x38
    temperature:
      name: "Temperature"
      id: temp
      icon: "mdi:thermometer"
    humidity:
      name: "Air Humidity"
      id: hum
      icon: "mdi:water-percent"
    update_interval: 15s

deep_sleep:
  run_duration: 60s
  sleep_duration: 1800s
  wakeup_pin:
    number: GPIO0
    inverted: True
  wakeup_pin_mode: IGNORE
  id: deep_sleep_1

Is there a way to force the microcontroller to initialize the I2C bus after each deep sleep recovery? Am I missing something on the code?

Thanks and best regards,

Jon

I’ve had similar issues and they’ve often related to connections and/or power supply. And maybe power demand spikes on boot from sleep.

As first steps (if you haven’t already), I would:

  1. Test with your best quality power supply and cables
  2. Triple check all of your connections and consider soldering them if they aren’t already.
  3. How long are your cables/wires to sensors? Test with short ones.

After some of those checks there are a few tricks I’ve seen people try like tinkering with delays, wire.begins and sensor setup priorities on boot. With what seems to be varying success.

My understanding is that a wake from deep sleep should be the same as a restart of the esp. However I agree with @Mahko_Mahko that there may be some timing it power issues.

Thanks for the tips @Mahko_Mahko, the circuit is all on a single PCB with good connections and short traces between uC and sensors. So I am 99.9% confident it is not a hardware issue: I monitored the boot peak in both scenarios (on a cold start and after returning from a deep sleep) and show almost the same value.

I am quite interested in your mention of a wire.begins instruction that could be set on boot, but I don’t see any ‘action’ like that to be set. Maybe with a lambda function?

esphome:
  name: device
  on_boot:
    priority: 1000
    then:
        ??? instruction for initializing the I2C bus ???

Thanks and best regards

See here…

Thanks for the link, seems to be something quite similar to what I intend. I tried to update mine in remote, but I guess the battery just run out. Will try later on and keep you posted.

1 Like

I found the working config:

  on_boot:
    priority: 600
    then:
     - lambda: |-
        Wire.begin();
        delay(100);

It was important to set the priority at 600 (the power up of the enabling pins had a highest priority).

3 Likes

Please could somebody explain to me, in simple terms, what this does?

Hi everyone!

I’ve noticed that in this old thread, and I’d like to provide an explanation and an example to help those who may be experiencing the same issue.

The function Wire.begin() is used to initialize I2C communication in ESP8266 or ESP32-based devices, like the ones we use with ESPHome. In the context of the on_boot block, it’s used to ensure that I2C communication is operational from the device’s boot, allowing its later use.

For Wire.begin() to work correctly, it’s necessary to load the corresponding component to handle I2C communication in ESPHome. This is achieved by configuring the I2C component in our YAML configuration file.

Here’s an example of how to configure the I2C component for an ESP32-S2 board in ESPHome:

yaml

# Example configuration for ESP32-S2
i2c:
  sda: 8
  scl: 9
  scan: true
  id: bus_a

With this configuration, the I2C component will initialize I2C communication on pins 8 and 9 (SDA and SCL respectively) when the device boots up.

I hope this explanation and example are helpful for those experiencing issues with Wire.begin() and I2C communication in ESPHome. If you have any additional questions, feel free to ask!

Best regards and happy coding!