ESP32-EVB-IND LAN8720 Component crashes when relays are toggled

Hello everyone,

I have flashed ESPHome 2025.4.1 to an Olimex ESP32-EVB-IND board.
The board has two relays, wifi and an LAN8720 Ethernet port.

Toggling the switches from Home Assistant works very well, when the Olimex Board is connected via Wifi. I can toggle the switches on and off repeatedly ( with and without load).

But when I connect the board via Ethernet and toggle the switch, that has a light bulb attached to it, I can only toggle it once and if I try a second time, the NIC seems to crash or become unresponsive. After that I can only look at UART output of the Board, but this does not show anything helpful either, except a message from ESPHome, that it will reboot, because it cannot reach Home Assistant anymore. Yet I can toggle the second switch with no load attached to it a thousand times without triggering this behaviour.

The board is described here:

  1. manual: ESP32-EVB/DOCS/ESP32-EVB-user-manual.pdf at 2e299f40f5114a3add74c942eb15b471417edff2 · OLIMEX/ESP32-EVB · GitHub
  2. wiring: ESP32-EVB/HARDWARE/REV-K1/ESP32-EVB_Rev_K1.pdf at 2e299f40f5114a3add74c942eb15b471417edff2 · OLIMEX/ESP32-EVB · GitHub

And the yaml I use looks like this:

esphome:
  name: solarsteuerung
  friendly_name: Solarsteuerung

esp32:
  board: esp32-evb
  flash_size: 4MB
  framework:
    type: esp-idf

# Enable logging
logger:
  level: VERY_VERBOSE

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

ota:
  - platform: esphome
    password: "YYY"

wifi:
  ssid: "mywifi"
  password: "ZZZ"

#ethernet:
#  type: LAN8720
#  mdc_pin: GPIO23
#  mdio_pin: GPIO18
#  clk_mode: GPIO0_IN
#  phy_addr: 0

one_wire:
  - platform: gpio
    pin: 16

sensor:
  - platform: dallas_temp
    address: 0x450623b23acfbb28
    name: "Solarsteuerung Puffertemperatur"
    update_interval: 20s
    icon: "mdi:thermometer"
    on_value:
      then:
        - lambda: !lambda |-
            if ((x >= id(solarsteuerung_temperaturschwelle_ein).state) &&
                      id(solarsteuerung_automatikbetrieb).state == 1.0 &&
                      !id(solarsteuerung_schalter_1).state) {
              id(solarsteuerung_schalter_1).turn_on();
              ESP_LOGI("main", "Puffertemperatur groesser als Einschaltwert, schalte Ein");
            } else if ((x <= id(solarsteuerung_temperaturschwelle_aus).state) &&
                             id(solarsteuerung_automatikbetrieb).state == 1.0 &&
                             id(solarsteuerung_schalter_1).state) {
              id(solarsteuerung_schalter_1).turn_off();
              ESP_LOGI("main", "Puffertemperatur kleiner als Ausschaltwert, schalte Aus");
            }

number:
  - platform: template
    name: "Solarsteuerung Temperaturschwelle EIN"
    id: solarsteuerung_temperaturschwelle_ein
    optimistic: true
    icon: "mdi:thermometer"
    initial_value: 100
    min_value: 0
    max_value: 200
    step: 5
    restore_value: true
    on_value:
      then:
        - lambda: !lambda |-
            if ( x <  (id(solarsteuerung_temperaturschwelle_aus).state)) {
              auto call = id(solarsteuerung_temperaturschwelle_aus).make_call();
              call.set_value(id(solarsteuerung_temperaturschwelle_ein).state - 20);
              call.perform();
              ESP_LOGI("main", "Einschaltwert kleiner als Ausschaltwert, verringere Ausschaltwert auf: %f", id(solarsteuerung_temperaturschwelle_aus).state);
            }
  - platform: template
    name: "Solarsteuerung Temperaturschwelle AUS"
    id: solarsteuerung_temperaturschwelle_aus
    optimistic: true
    icon: "mdi:thermometer"
    initial_value: 60
    min_value: 0
    max_value: 200
    step: 5
    restore_value: true
    on_value:
      then:
        - lambda: !lambda |-
            if ( x >  (id(solarsteuerung_temperaturschwelle_ein).state)) {
              auto call = id(solarsteuerung_temperaturschwelle_ein).make_call();
              call.set_value(id(solarsteuerung_temperaturschwelle_aus).state + 20);
              call.perform();
              ESP_LOGI("main", "Ausschaltwert groesser als Einschaltwert, erhoehe Einschaltwert auf: %f", id(solarsteuerung_temperaturschwelle_ein).state);
            }

switch:
  - platform: restart
    name: "Neustart"
    id: solarsteuerung_neustart
  - platform: gpio
    name: "Solarsteuerung Schalter 1"
    id: solarsteuerung_schalter_1
    pin: 32
  - platform: gpio
    name: "Solarsteuerung Schalter 2"
    id: solarsteuerung_schalter_2
    pin: 33
  - platform: template
    name: "Automatikbetrieb AN/AUS"
    id: solarsteuerung_automatikbetrieb
    optimistic: true
    icon: "mdi:cog-play-outline"
    restore_mode: RESTORE_DEFAULT_ON

select:
  - platform: logger
    name: "Logger select"

Although there are some lambdas in this yaml, I used only the switches for testing. The ethernet section is straight from the wiki and seems to line up with the wiring diagram.

Once the Olimex becomes “not available” from Home Assistants point of view, I can see the following logs via UART:

[E][api:129]: No client connected to API. Rebooting...
[I][app:125]: Forcing a reboot...
[I][ethernet:604]: Powering down ethernet PHYets Jul 29 2019 12:21:46

...

[C][ethernet:041]: Setting up Ethernet...
[D][esp-idf:000]: E (1141) eth_phy_802_3: esp_eth_phy_802_3_pwrctl(250): power up timeout
[D][esp-idf:000]: E (1141) eth_phy_802_3: esp_eth_phy_802_3_basic_phy_init(433): power control failed
[D][esp-idf:000]: E (1142) lan87xx: lan87xx_init(341): failed to init PHY
[D][esp-idf:000]: E (1142) esp_eth: esp_eth_driver_install(229): init phy failed
[E][ethernet:204]: ETH driver install error: (-1) ESP_FAIL
[E][component:119]: Component ethernet was marked as failed.
[E][component:164]: Component ethernet set Error flag: unspecified

I would appreciate any help, I asked over at discord, where we discussed the possibility of a faulty power supply, tbh. I would rule it out, because switching works very well in wifi mode. Is there any way to get more information or insights? Even Very Verbose Logging mode does not seem to give a clue, why the NIC becomes unreachable for ESPHome.

Thanks,

after some time the board forces itself to reboot and some error messages about the ethernet driver can be seen when the boot is complete:

[E][api:129]: No client connected to API. Rebooting...
[I][app:125]: Forcing a reboot...
[I][ethernet:604]: Powering down ethernet PHYets Jul 29 2019 12:21:46

rst:0xc (SW_CPU_RESET),boot:0x1b (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:7112
load:0x40078000,len:15624
load:0x40080400,len:4
load:0x40080404,len:3876
entry 0x4008064c
I (29) boot: ESP-IDF 5.1.5 2nd stage bootloader
I (29) boot: compile time May  3 2025 10:00:37
I (29) boot: Multicore bootloader
I (33) boot: chip revision: v3.1
I (37) boot.esp32: SPI Speed      : 40MHz
I (42) boot.esp32: SPI Mode       : DIO
I (46) boot.esp32: SPI Flash Size : 4MB
I (51) boot: Enabling RNG early entropy source...
I (56) boot: Partition Table:
I (60) boot: ## Label            Usage          Type ST Offset   Length
I (67) boot:  0 otadata          OTA data         01 00 00009000 00002000
I (75) boot:  1 phy_init         RF data          01 01 0000b000 00001000
I (82) boot:  2 app0             OTA app          00 10 00010000 001c0000
I (90) boot:  3 app1             OTA app          00 11 001d0000 001c0000
I (97) boot:  4 nvs              WiFi data        01 02 00390000 0006d000
I (105) boot: End of partition table
I (109) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=227e0h (141280) map
I (168) esp_image: segment 1: paddr=00032808 vaddr=3ffb0000 size=021cch (  8652) load
I (172) esp_image: segment 2: paddr=000349dc vaddr=40080000 size=0b63ch ( 46652) load
I (194) esp_image: segment 3: paddr=00040020 vaddr=400d0020 size=56590h (353680) map
I (322) esp_image: segment 4: paddr=000965b8 vaddr=4008b63c size=015e8h (  5608) load
I (331) boot: Loaded app from partition at offset 0x10000
I (331) boot: Disabling RNG early entropy source...
I (344) cpu_start: Multicore app
I (345) cpu_start: Pro cpu up.
I (345) cpu_start: Starting app cpu, entry point is 0x40081f94
I (333) cpu_start: App cpu up.
I (362) cpu_start: Pro cpu start user code
I (362) cpu_start: cpu freq: 160000000 Hz
I (362) cpu_start: Application information:
I (367) cpu_start: Project name:     solarsteuerung
I (373) cpu_start: App version:      2025.4.1
I (378) cpu_start: Compile time:     May  3 2025 12:44:49
I (384) cpu_start: ELF file SHA256:  c382be9fa53fe593...
I (390) cpu_start: ESP-IDF:          5.1.5
I (395) cpu_start: Min chip rev:     v0.0
I (399) cpu_start: Max chip rev:     v3.99
I (404) cpu_start: Chip rev:         v3.1
I (409) heap_init: Initializing. RAM available for dynamic allocation:
I (416) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (422) heap_init: At 3FFB3948 len 0002C6B8 (177 KiB): DRAM
I (428) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (435) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (441) heap_init: At 4008CC24 len 000133DC (76 KiB): IRAM
I (449) spi_flash: detected chip: generic
I (452) spi_flash: flash io: dio
I (457) app_start: Starting scheduler on CPU0
I (461) app_start: Starting scheduler on CPU1
I (461) main_task: Started on CPU0
I (471) main_task: Calling app_main()
I [I][logger:171]: Log initialized
[VV][esp32.preferences:071]: nvs_get_blob: key: 233825507, len: 4
[C][safe_mode:079]: There have been 0 suspected unsuccessful boot attempts
[VV][esp32.preferences:040]: s_pending_save: key: 233825507, len: 4
[D][esp32.preferences:114]: Saving 1 preferences to flash...
[VV][esp32.preferences:123]: Checking if NVS data 233825507 has changed
[V][esp32.preferences:126]: sync: key: 233825507, len: 4
[D][esp32.preferences:142]: Saving 1 preferences to flash: 0 cached, 1 written, 0 failed
[I][app:029]: Running through setup()...
[V][app:030]: Sorting components by setup priority...
[C][gpio.one_wire:011]: Setting up 1-wire bus...
[VV][esp-idf:000]: I (673) gpio: GPIO[16]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
[V][esp32.preferences:059]: nvs_get_blob('1040736654'): ESP_ERR_NVS_NOT_FOUND - the key might not be set yet
[D][number:012]: 'Solarsteuerung Temperaturschwelle EIN': Sending state 100.000000
[V][esp32.preferences:059]: nvs_get_blob('1242759763'): ESP_ERR_NVS_NOT_FOUND - the key might not be set yet
[D][number:012]: 'Solarsteuerung Temperaturschwelle AUS': Sending state 60.000000
[C][switch.gpio:011]: Setting up GPIO Switch 'Solarsteuerung Schalter 1'...
[D][switch:016]: 'Solarsteuerung Schalter 1' Turning OFF.
[D][switch:055]: 'Solarsteuerung Schalter 1': Sending state OFF
[VV][esp-idf:000]: I (745) gpio: GPIO[32]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
[D][switch:016]: 'Solarsteuerung Schalter 1' Turning OFF.
[C][switch.gpio:011]: Setting up GPIO Switch 'Solarsteuerung Schalter 2'...
[D][switch:016]: 'Solarsteuerung Schalter 2' Turning OFF.
[D][switch:055]: 'Solarsteuerung Schalter 2': Sending state OFF
[VV][esp-idf:000]: I (776) gpio: GPIO[33]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
[D][switch:016]: 'Solarsteuerung Schalter 2' Turning OFF.
[VV][esp32.preferences:071]: nvs_get_blob: key: 2260899601, len: 1
[D][template.switch:046]:   Restored state ON
[D][switch:012]: 'Automatikbetrieb AN/AUS' Turning ON.
[VV][esp32.preferences:040]: s_pending_save: key: 2260899601, len: 1
[D][switch:055]: 'Automatikbetrieb AN/AUS': Sending state ON
[D][select:015]: 'Logger select': Sending state VERY_VERBOSE (index 7)
[C][ethernet:041]: Setting up Ethernet...
[VV][esp-idf:000]: E (1261) eth_phy_802_3: esp_eth_phy_802_3_pwrctl(250): power up timeout
[VV][esp-idf:000]: E (1261) eth_phy_802_3: esp_eth_phy_802_3_basic_phy_init(433): power control failed
[VV][esp-idf:000]: E (1262) lan87xx: lan87xx_init(341): failed to init PHY
[VV][esp-idf:000]: E (1262) esp_eth: esp_eth_driver_install(229): init phy failed
[E][ethernet:204]: ETH driver install error: (-1) ESP_FAIL
[E][component:119]: Component ethernet was marked as failed.
[E][component:164]: Component ethernet set Error flag: unspecified
[D][esp32.preferences:114]: Saving 1 preferences to flash...
[VV][esp32.preferences:123]: Checking if NVS data 2260899601 has changed
[V][esp32.preferences:137]: NVS data not changed skipping 2260899601  len=1
[D][esp32.preferences:142]: Saving 1 preferences to flash: 1 cached, 0 written, 0 failed

Ok, so I attached my lamp to switch number 2 and now it seems to work without a problem. Could this be a configuration issue, because one switch uses PIN 33 and the other PIN 32 or is it more likely to be just a faulty board?

Is the “empty” switch1 now working as well?
Is it LED lamp?

Sadly switch 1 still doesn’t work with anything attached.
It does “work” if nothing is attached though.
The lamp is indeed an LED lamp, I tried two different LED lamps.
Connected to switch 2 both of those lamps work.

Sounds some problem with the relay itself or interference from output.
What about some purely resistive load? Like incandescent bulb?

that is a good idea, I think I have one available at another place.
I will try to test that, might take some time though.

Cheap LED lights (drivers) cause lot of trouble with relays and capacitors. RC-snubber should be used.

I did some more testing together with the guys over at Olimex and used a hairdryer and extension cords. We came to the conclusion, that it is probably a faulty board.