How to use ESP32 dev kit v1 with LAN8720

Hello everyone

I would like to know if any of you have already used a LAN8720 with an ESP32 devkit v1.
Because I've been trying to make it work for weeks without success.
Do you have a connection diagram, as well as a simple program to make it work?

For your information, here is a program that I used:

/*
 This sketch shows how to use lan8720 with esp32 with minimal/standard configuration
 
 You can set the parameter in begin function or at start with define before the import
 of ETH.h file, this way is preferible.
 
 by Renzo Mischianti <mischianti.org>
 */
 
// I²C-address of Ethernet PHY (0 or 1 for LAN8720, 31 for TLK110)
#define ETH_PHY_ADDR 1                      // DEFAULT VALUE IS 0 YOU CAN OMIT IT
// Type of the Ethernet PHY (LAN8720 or TLK110)
#define ETH_PHY_TYPE ETH_PHY_LAN8720        // DEFAULT VALUE YOU CAN OMIT IT
// Pin# of the enable signal for the external crystal oscillator (-1 to disable for internal APLL source)
#define ETH_PHY_POWER -1                    // DEFAULT VALUE YOU CAN OMIT IT
// Pin# of the I²C clock signal for the Ethernet PHY
#define ETH_PHY_MDC 23                      // DEFAULT VALUE YOU CAN OMIT IT
// Pin# of the I²C IO signal for the Ethernet PHY
#define ETH_PHY_MDIO 18                     // DEFAULT VALUE YOU CAN OMIT IT
// External clock from crystal oscillator
#define ETH_CLK_MODE ETH_CLOCK_GPIO17_OUT     // DEFAULT VALUE YOU CAN OMIT IT
 
#include <ETH.h>
 
static bool eth_connected = false;
 
void WiFiEvent(WiFiEvent_t event) {
  Serial.println(event);
    switch (event) {
    case ARDUINO_EVENT_ETH_START:
        Serial.println("ETH Started");
        ETH.setHostname("esp32-mischianti-eth");
        break;
    case ARDUINO_EVENT_ETH_CONNECTED:
        Serial.println("ETH Connected");
        break;
    case ARDUINO_EVENT_ETH_GOT_IP:
        Serial.print("ETH MAC: ");
        Serial.print(ETH.macAddress());
        Serial.print(", IPv4: ");
        Serial.print(ETH.localIP());
        if (ETH.fullDuplex()) {
            Serial.print(", FULL_DUPLEX");
        }
        Serial.print(", ");
        Serial.print(ETH.linkSpeed());
        Serial.println("Mbps");
        eth_connected = true;
        break;
    case ARDUINO_EVENT_ETH_DISCONNECTED:
        Serial.println("ETH Disconnected");
        eth_connected = false;
        break;
    case ARDUINO_EVENT_ETH_STOP:
        Serial.println("ETH Stopped");
        eth_connected = false;
        break;
    default:
        break;
    }
}
 
void testClient(const char *host, uint16_t port) {
    Serial.print("\nconnecting to ");
    Serial.println(host);
 
    WiFiClient client;
    if (!client.connect(host, port)) {
        Serial.println("connection failed");
        return;
    }
    client.printf("GET / HTTP/1.1\r\nHost: %s\r\n\r\n", host);
    while (client.connected() && !client.available())
        ;
    while (client.available()) {
        Serial.write(client.read());
    }
 
    Serial.println("closing connection\n");
    client.stop();
}
 
void setup() {
    Serial.begin(115200);
    WiFi.onEvent(WiFiEvent);
    ETH.begin();
}
 
void loop() {
    if (eth_connected) {
        testClient("mischianti.org", 80);
    }
    delay(10000);
 
}

And my connections :

|GPIO21   |  TX_EN|EMAC_TX_EN|
|GPIO19   |  TX0|EMAC_TXD0|
|GPIO22   |  TX1|EMAC_TXD1|
|GPIO25   |  RX0|EMAC_RXD0|
|GPIO26   |  RX1|EMAC_RXD1|
|GPIO27   |  CRS_DV|EMAC_RX_DRV|
|GPIO17   |  EMAC_CLK_180|REFCLK|
|GPIO23   |  MDC|Output to PHY|
|GPIO18   |  MDIO|Bidirectional|

Thanks in advance

I did it last week. I had only one problem:
#define ETH_PHY_ADDR 0 didn't work
#define ETH_PHY_ADDR -1 (auto) did

clock must be io 0, because for LAN8720 it is input and io 16 or 17 can only work as clock output

for wiring I followed Integrating LAN8720 with ESP32 for Ethernet Connectivity with plain (HTTP) and SSL (HTTPS) – Renzo Mischianti
(for me it worked without the patch even I had exactly that module)

btw for esp32 platform 3 I made EthernetESP32 library which as the same API as the Arduino Ethernet library unlike the ETH.h

Thanks @Juraj,

How did you use io 0, when it is already used for the boot button ?

Because the ESP32 dev kit v1 does not have an accessible io 0 pin

my ESP32 dev kit by Espressif has io 0. boot button is only read at boot.

but I didn't use the Dev Kit because it is wide for the breadboard. I used an ESP32 D1 mini

I'm going to try it with an ESP32 D1 mini, I found one in my drawers.

I redid the wiring with the ESP32 Di mini, with the patch and without the patch.
I still can't get a network connection.
Could you give me a hand because I'm completely lost now.

the patch is necessary, if the esp32 doesn't start the sketch with LAN8720 wired to io 0..

did you change in sketch the ETH_PHY_ADDR to -1?

I did these tests below, using the corresponding program with or without patch

Test No. 1, LAN8720 without patch and ADDR -1:

20:16:17.635 -> rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
20:16:17.635 -> configsip: 0, SPIWP:0xee
20:16:17.635 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
20:16:17.635 -> mode:DIO, clock div:1
20:16:17.635 -> load:0x3fff0030,len:1184
20:16:17.635 -> load:0x40078000,len:13260
20:16:17.635 -> load:0x40080400,len:3028
20:16:17.635 -> entry 0x400805e4
20:16:18.025 -> E (121) lan87xx: lan87xx_pwrctl(409): power up timeout
20:16:18.025 -> E (121) lan87xx: lan87xx_init(491): power control failed
20:16:18.025 -> E (121) esp_eth: esp_eth_driver_install(215): init phy failed

Test No. 2, LAN8720 without patch and ADDR 1:

20:14:43.983 -> rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
20:14:43.983 -> configsip: 0, SPIWP:0xee
20:14:43.983 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
20:14:43.983 -> mode:DIO, clock div:1
20:14:43.983 -> load:0x3fff0030,len:1184
20:14:43.983 -> load:0x40078000,len:13260
20:14:43.983 -> load:0x40080400,len:3028
20:14:43.983 -> entry 0x400805e4
20:14:45.983 -> ETH Started
20:14:45.983 -> ETH Connected

Test No. 2, LAN8720 with patch and ADDR 1:

20:19:49.324 -> rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
20:19:49.324 -> configsip: 0, SPIWP:0xee
20:19:49.324 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
20:19:49.324 -> mode:DIO, clock div:1
20:19:49.324 -> load:0x3fff0030,len:1184
20:19:49.324 -> load:0x40078000,len:13260
20:19:49.324 -> load:0x40080400,len:3028
20:19:49.324 -> entry 0x400805e4
20:19:53.652 -> ETH Started

Test No. 4, LAN8720 with patch and ADDR -1:

20:22:01.501 -> rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
20:22:01.501 -> configsip: 0, SPIWP:0xee
20:22:01.501 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
20:22:01.501 -> mode:DIO, clock div:1
20:22:01.501 -> load:0x3fff0030,len:1184
20:22:01.501 -> load:0x40078000,len:13260
20:22:01.501 -> load:0x40080400,len:3028
20:22:01.501 -> entry 0x400805e4
20:22:01.901 -> E (122) lan87xx: lan87xx_pwrctl(409): power up timeout
20:22:01.901 -> E (122) lan87xx: lan87xx_init(491): power control failed
20:22:01.901 -> E (122) esp_eth: esp_eth_driver_install(215): init phy failed

so it looks like ADDR 1 is OK.
is the LAN module properly connected with a cable to a switch or router?

EDIT: Is there a DHCP server on the network you are connecting to?

The LAN8720 module is connected to a hub which is connected to the router.
I don't know if I have a DHCP server on my network.

After multiple attempts, I have the result below, but unable to retrieve the Mac address and local IP.
Do you have an idea?

18:36:58.468 -> rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
18:36:58.468 -> configsip: 0, SPIWP:0xee
18:36:58.468 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
18:36:58.468 -> mode:DIO, clock div:1
18:36:58.468 -> load:0x3fff0030,len:1184
18:36:58.468 -> load:0x40078000,len:13260
18:36:58.468 -> load:0x40080400,len:3028
18:36:58.468 -> entry 0x400805e4
18:37:00.480 -> ETH Started
18:37:00.480 -> ETH Connected

Code :

/*
 This sketch shows how to use lan8720 with esp32 with minimal/standard configuration
 
 You can set the parameter in begin function or at start with define before the import
 of ETH.h file, this way is preferible.
 
 by Renzo Mischianti <mischianti.org>
 */
 
// I²C-address of Ethernet PHY (0 or 1 for LAN8720, 31 for TLK110)
#define ETH_PHY_ADDR 1                      // DEFAULT VALUE IS 0 YOU CAN OMIT IT
// Type of the Ethernet PHY (LAN8720 or TLK110)
#define ETH_PHY_TYPE ETH_PHY_LAN8720        // DEFAULT VALUE YOU CAN OMIT IT
// Pin# of the enable signal for the external crystal oscillator (-1 to disable for internal APLL source)
#define ETH_PHY_POWER -1                    // DEFAULT VALUE YOU CAN OMIT IT
// Pin# of the I²C clock signal for the Ethernet PHY
#define ETH_PHY_MDC 23                      // DEFAULT VALUE YOU CAN OMIT IT
// Pin# of the I²C IO signal for the Ethernet PHY
#define ETH_PHY_MDIO 18                     // DEFAULT VALUE YOU CAN OMIT IT
// External clock from crystal oscillator
#define ETH_CLK_MODE ETH_CLOCK_GPIO0_IN     // DEFAULT VALUE YOU CAN OMIT IT
 
#include <ETH.h>
 
static bool eth_connected = false;
 
void WiFiEvent(WiFiEvent_t event) {
    switch (event) {
    case ARDUINO_EVENT_ETH_START:
        Serial.println("ETH Started");
        ETH.setHostname("esp32-mischianti-eth");
        break;
    case ARDUINO_EVENT_ETH_CONNECTED:
        Serial.println("ETH Connected");
        break;
    case ARDUINO_EVENT_ETH_GOT_IP:
        Serial.print("ETH MAC: ");
        Serial.print(ETH.macAddress());
        Serial.print(", IPv4: ");
        Serial.print(ETH.localIP());
        if (ETH.fullDuplex()) {
            Serial.print(", FULL_DUPLEX");
        }
        Serial.print(", ");
        Serial.print(ETH.linkSpeed());
        Serial.println("Mbps");
        eth_connected = true;
        break;
    case ARDUINO_EVENT_ETH_DISCONNECTED:
        Serial.println("ETH Disconnected");
        eth_connected = false;
        break;
    case ARDUINO_EVENT_ETH_STOP:
        Serial.println("ETH Stopped");
        eth_connected = false;
        break;
    default:
        break;
    }
}
 
void testClient(const char *host, uint16_t port) {
    Serial.print("\nconnecting to ");
    Serial.println(host);
 
    WiFiClient client;
    if (!client.connect(host, port)) {
        Serial.println("connection failed");
        return;
    }
    client.printf("GET / HTTP/1.1\r\nHost: %s\r\n\r\n", host);
    while (client.connected() && !client.available())
        ;
    while (client.available()) {
        Serial.write(client.read());
    }
 
    Serial.println("closing connection\n");
    client.stop();
}
 
void setup() {
    Serial.begin(115200);
    WiFi.onEvent(WiFiEvent);
    ETH.begin();
}
 
void loop() {
    if (eth_connected) {
        testClient("mischianti.org", 80);
    }
    delay(10000);
 
}

try it with static IP.

  IPAddress ip(192, 168, 1, 177);
  IPAddress gw(192, 168, 1, 1);
  IPAddress dns(8, 8, 8, 8);
  IPAddress mask(255, 255, 255, 0);

ETH.begin();
ETH.config(ip, gw, subnet, mask);

use valid addresses for you network

Thanks @Juraj

We are making progress but it is still not operational.
However, I modified:

ETH.config(ip, gw, subnet, mask);

By :

ETH.config(ip, gw, dns, mask);

The code for my network:

void setup() {
  Serial.begin(115200);
  WiFi.onEvent(WiFiEvent);
  IPAddress ip(192, 168, 0, 42);
  IPAddress gw(192, 168, 0, 1);
  IPAddress dns(89, 2, 0, 1);
  IPAddress mask(255, 255, 255, 0);

  ETH.begin();
  ETH.config(ip, gw, dns, mask);
}

And here is the return of the serial monitor:

10:50:25.710 -> rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
10:50:25.710 -> configsip: 0, SPIWP:0xee
10:50:25.710 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
10:50:25.710 -> mode:DIO, clock div:1
10:50:25.710 -> load:0x3fff0030,len:1184
10:50:25.710 -> load:0x40078000,len:13260
10:50:25.710 -> load:0x40080400,len:3028
10:50:25.710 -> entry 0x400805e4
10:50:27.512 -> ETH Started
10:50:27.512 -> ETH Connected
10:50:27.557 -> ETH MAC: 4C:11:AE:74:DB:6B, IPv4: 192.168.0.42, FULL_DUPLEX, 100Mbps
10:50:27.557 -> 
10:50:27.557 -> connecting to mischianti.org
10:50:34.560 -> connection failed
10:50:44.552 -> 
10:50:44.552 -> connecting to mischianti.org
10:50:51.581 -> connection failed
10:51:01.542 -> 
10:51:01.542 -> connecting to mischianti.org
10:51:08.563 -> connection failed

On my box I can clearly see my esp32 with my Ethernet module:

But I don't receive any ping:

C:\Users\treza>ping 192.168.0.42

Envoi d’une requête 'Ping'  192.168.0.42 avec 32 octets de données :
Délai d’attente de la demande dépassé.
Délai d’attente de la demande dépassé.
Délai d’attente de la demande dépassé.
Délai d’attente de la demande dépassé.

Statistiques Ping pour 192.168.0.42:
    Paquets : envoyés = 4, reçus = 0, perdus = 4 (perte 100%),

check the wiring of the RMII pins especially RX pins

I just checked.
The wiring is good, I have continuity between the ESP pins and the LAN8720 pins

but are they on the correct pin?

I rechecked the pin connections and even several times

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.