ESPhome: one_wire + i2c device interference? timing issue? (ESP32-ETH01 v1.4)

Hi all,

I encountered a strange problem … first things first:
Home assistant (run as VM on a proxmox host):
Core 2024.9.1
Supervisor 2024.09.1
Operating System 13.1
Frontend 20240906.0

ESPHome 2024.8.3

I built a smart PDU for my Network/Server rack using an ESP32-ETH01 v1.4.
Due to the ethernet, the board has relatively few GPIOs pins that can be used and some even cause problems when they are used (e.g. GPIO1, 2, 0), so I am using two multiplexer (MCP23017) via I2C and control everything I can via them. Something that cannot be controlled via the multiplexer is a one-wire connection. So, I am using GPIO4 for a DS18B20 (one_wire) to control the temperature of my PDU in the case.

Everything worked just fine, but recently I added a front panel to the rack with push buttons and LED status indicator that control and indicate the status of the PDU’s relays. The front panel also contains an SDS1306 OLED display (I2C). To reduce the amount of cables to run from the PDU to the front panel, I am running 4 wires for the I2C from the PDU to the front panel and attached the second GPIO multiplexer (MCP23017) there together with the OLED.
On the ESP32-ETH01 v1.4, I use GPIO15 for SDA and GPIO2 for SCL.
(Both are strapping pins, but I can’t use any others, because they are all in use; except for 14 and 12, but when I use them the ethernet doesn’t work anymore).

Before adding the OLED and the second GPIO multiplexer via I2C, everything worked, including the one_wire/DS18B20 temperature sensor.

After adding the OLED and the second GPIO multiplexer via I2C, everything works too, except for the one_wire/DS18B20 temperature sensor. The logs always say:

[13:45:15][C][gpio.one_wire:021]: Pin: GPIO4
[13:45:15][W][gpio.one_wire:078]: Found no devices!

I don’t use an external pull-up resistor, because one_wire uses an internal one (up to my knowledge).
I did some tests and concluded that it is very likely some kind of timing issue:

  • I tested the DS18B20 on another ESP32 and it worked fine (same config for the DS18B20)
  • I tested a different DS18B20 on the same ESP32-ETH01 v1.4
  • I checked the power at the sensor, stable 3.3V.
  • I played around with the one_wire update interval - no success
  • I increased the logging to very verbose and then something interesting happened: EVERYTHING worked, including the DS18B20, just by increasing the log level to very verbose. Of course I can’t leave it like that, so I reduced the logging level to DEBUG, but then the problem cam back.

This indicats that it is likely a timing issue. So, I:

  • added a delay before sensor initialization and after boot up (normal logging) - no success
  • increased the I2C bus frequency to 400 kHz - no success
  • I took the one_wire address from the very verbose logging and provided it directly in the config. In this case the sensor is found, but it reports 0°C and doesn’t change.

So far only increasing the logging level to very verbose helped, but that’s not a solution.
I am not 100% sure, but I might also have updated ESPhome on the ESP when I added the front panel components - not sure if that could be an issue too?

Below my reduced (for clarity) config:

esphome:
  name: "esp32-eth01-rack01"
  friendly_name: "esp32-eth01-rack01"
  platform: ESP32
  board: esp-wrover-kit

  # Ensure fan state is checked at startup #### FAN CONTROL
  on_boot:
    priority: 600 # After the sensor initialization
    then:
      #- delay: 5s  # Add a 5-second delay before initializing the rest
      - script.execute: set_fan01_speed_from_DHT22_01_temp # for clarity corresponding parts removed below
      - script.execute: set_fan02_speed_from_DHT22_02_temp # for clarity corresponding parts removed below


ethernet:
  type: LAN8720
  mdc_pin: GPIO23
  mdio_pin: GPIO18
  clk_mode: GPIO0_IN
  phy_addr: 1
  power_pin: GPIO16


logger:
  #level: VERY_VERBOSE
  #level: DEBUG
  #level: DEBUG  # General logging level
  #logs:
  #  dallas: VERY_VERBOSE  # Set only the Dallas component to very verbose


# Enable Home Assistant API
api:
  #### removed for clarity


ota:
  #### removed for clarity


# Global variable to track manual override state
globals:
  #### removed for clarity


#for Pressure sensor (BMP/E280), BMP has no humidity
i2c:
  - id: bus_a
    sda: GPIO15
    scl: GPIO2
    scan: True
    #frequency: 400kHz  

mcp23017:
  - id: mcp23017_hub
    address: 0x20 #A0,A1,A3=GND
    i2c_id: bus_a
  - id: mcp23017_hub_ext_panel
    address: 0x21 #A0=VCC, A1,A2=GND
    i2c_id: bus_a

# one_wire always uses internal pull-up resistor by default! no need to add one
one_wire:
  - platform: gpio
    pin: GPIO4
    id: ds18b20

switch:
  - platform: gpio
    name: "relay01"
    id: relay01
    pin: 
      mcp23xxx: mcp23017_hub
      number: 0 # PA0
      inverted: true
      mode:
        output: true
  # Template switch to control the relay and ensure LED syncs with relay state
  - platform: template
    name: "Relay 01 with LED Sync"
    id: relay01_template
    optimistic: true
    turn_on_action:
      - switch.turn_on: relay01
      - output.turn_on: LED_relay01
    turn_off_action:
      - switch.turn_off: relay01
      - output.turn_off: LED_relay01
   #### rest removed for clarity




sensor:
  #### block removed for clarity

  - platform: dallas_temp
    one_wire_id: ds18b20
    #address: "0x08030d979422cf28"
    name: "PDU_temperature"
    id: PDU_temperature
    update_interval: 60s

  #### block removed for clarity



binary_sensor:
  - platform: gpio
    id: button_relay01
    pin: 
      mcp23xxx: mcp23017_hub_ext_panel
      number: 0 
      inverted: true
      mode:
        input: true
        pullup: true
    name: "button_relay01"
    device_class: ''
    filters:
      - delayed_on: 5ms
    on_press:
      - switch.toggle: relay01_template  # Toggle relay when button is pressed
  #### block removed for clarity


font:
  #### block removed for clarity


display:
  - platform: ssd1306_i2c
    i2c_id: bus_a
    model: "SSD1306 128x64"
    #address: 0x3C
    rotation: 0° 
    contrast: 100%
    update_interval: 1s 
    id: my_display
    lambda: |-
      it.print(0, 0, id(roboto_20), "Hello World!");
    #### block in lambda removed for clarity



output:
  #### block removed for clarity
  
  ####### OUTPUT - LEDs on relay buttons on front panel
  - platform: gpio
    pin:
      mcp23xxx: mcp23017_hub_ext_panel
      number: 8  
    id: 'LED_relay01'
  #### block removed for clarity


fan:
  #### block removed for clarity

script:
  #### block removed for clarity

number:
  #### block removed for clarity

Has anyone an idea how I could fix this?

Thanks a lot!

Just updates ESPhome again (from 2024.8.3 to 2024.9.0) … the DS18D20 sensor works again!
So it must have been a bug with the last ESPhome version.