Skip to content

EthernetModule

Implemented in Sprint 11. Replaces the Sprint 8 stub with a full Ethernet driver supporting DHCP and static IP modes.


What it does

EthernetModule initialises Ethernet hardware via the PAL layer and polls the link state every second. When the link comes up it reads the assigned IP address and updates the status and ip_address controls. NetworkModule calls isConnected() each management tick to gate the WiFi AP.

Two hardware variants are supported, selected at compile time via platformio.ini build flags:

Board Hardware Interface Flag
esp32dev LAN8720A RMII (GPIO) -DPMM_ETH_LAN8720
esp32s3_n16r8 W5500 SPI -DPMM_ETH_W5500

On PC (no Ethernet hardware compiled in) status is "unsupported" and all PAL calls are no-ops.


Controls

Key Type Persisted Description
status display no "unsupported" / "initialising" / "init_failed" / "disconnected" / "connected"
ip_address display no Current IP address; empty when disconnected
mode select yes "dhcp" (default) or "static"
static_ip text yes Static IP address (e.g. 192.168.5.1); only used when mode == "static"
static_gateway text yes Gateway IP; defaults to the static IP with the last octet set to 1 if left empty
static_subnet text yes Subnet mask; defaults to 255.255.255.0

Changing mode or any static_* field takes effect immediately if Ethernet is already initialised.


IP configuration

DHCP (default)

Leave mode as "dhcp". The module calls ETH.begin() and waits for a DHCP lease. status becomes "connected" and ip_address shows the assigned IP.

Static IP

Set mode to "static" and fill in static_ip. Optionally set static_gateway and static_subnet (both have sensible defaults). The new config is applied immediately via ETH.config().


Direct-connect mode

When the ESP32 is wired directly to a laptop (no router, no DHCP server), use static IP:

  1. In the UI, set mode = "static", static_ip = "192.168.5.1", static_gateway = "192.168.5.1".
  2. On the laptop, set a manual IP: 192.168.5.2, subnet 255.255.255.0, no gateway.
  3. The device is reachable at http://192.168.5.1.

This is the Ethernet equivalent of the WiFi AP: a known fixed address that does not require a router.

Link-local (169.254.x.x): If mode == "dhcp" and no DHCP server is present, lwIP may auto-assign a 169.254 address after a timeout. Modern OSes do the same. This provides a zero-config direct-connect path, but the address is non-deterministic. Static mode is preferred for direct connect.

NetworkModule interaction: when Ethernet connects, NetworkModule's management tick disables both the WiFi AP and STA. When Ethernet drops, STA is re-enabled so it can reconnect automatically. For the full policy (timers, grace period, state diagram), see Developer Guide: Network — Management policy.


Pin configuration (platformio.ini)

Pin assignments are compile-time constants defined in platformio.ini. Adjust for your specific board:

LAN8720 (esp32dev):

build_flags =
    -DPMM_ETH_LAN8720
    -DETH_RMII_PHY_ADDR=1        ; PHY address: 0 or 1 depending on board
    -DETH_RMII_MDC=23
    -DETH_RMII_MDIO=18
    -DETH_CLK_MODE=ETH_CLOCK_GPIO0_IN  ; external oscillator on GPIO0 (most boards)

W5500 (esp32s3_n16r8):

build_flags =
    -DPMM_ETH_W5500
    -DETH_SPI_HOST=2             ; 1 = SPI2/FSPI, 2 = SPI3/HSPI
    -DETH_SPI_FREQ=25000000
    -DETH_SPI_MOSI=11
    -DETH_SPI_MISO=13
    -DETH_SPI_SCK=12
    -DETH_SPI_CS=10
    -DETH_SPI_IRQ=4


healthReport format

Condition Output
PC / no hardware eth=unsupported
Hardware present, link down eth=disconnected
Hardware present, link up eth=connected ip=192.168.1.42

Test coverage

See Network and WiFi tests. PC tests cover:

  • Lifecycle does not crash
  • status is "unsupported" on PC (no hardware flag)
  • healthReport returns eth=unsupported
  • isConnected() returns false
  • loadState/saveState round-trip for mode and static_ip
  • Default static_subnet is 255.255.255.0

Source