Overview
The W5500 module gives your microcontroller a wired Ethernet port — and with it, the reliability WiFi can't promise. The WIZnet W5500 chip is a "hardwired TCP/IP" controller: the entire TCP/IP stack (TCP, UDP, IPv4, ICMP, ARP, DHCP-capable sockets) runs in silicon, your microcontroller just talks to it over SPI. That means an Arduino Uno with 2KB of RAM can hold eight simultaneous network sockets, and your code never fights the radio-noise, reconnect, and latency gremlins of wireless.
The board carries the W5500, a magjack RJ45 with link/activity LEDs, a 3.3V regulator, and a 2x5 SPI header (plus the same signals on breakout rows). Wire four SPI lines and power, plug in any Ethernet cable to your router or switch, and DHCP hands you an IP address seconds later. 10/100 Mbps auto-negotiation, auto-MDIX on most boards, and support in every major ecosystem: the Arduino Ethernet library treats it as the default hardware, and CircuitPython/MicroPython drivers cover the Pi Pico world.
Reach for wired Ethernet where dropouts are unacceptable or WiFi can't go: home-automation hubs and MQTT brokers' clients, industrial monitoring, PoE-powered installs (with a PoE splitter), metal enclosures and basements that kill RF, and anything that must survive a router reboot unattended. It's also the easy path to networking for boards with no radio at all — like the standard Pico.
At a Glance
Specifications
| Parameter | Value |
| Chipset | WIZnet W5500 hardwired TCP/IP controller |
| Protocols in Hardware | TCP, UDP, IPv4, ICMP, ARP, IGMP, PPPoE |
| Simultaneous Sockets | 8 independent hardware sockets |
| Buffer Memory | 32 KB internal TX/RX buffers |
| PHY | 10BASE-T / 100BASE-TX, auto-negotiation |
| Host Interface | SPI Mode 0/3, up to 80 MHz |
| Supply | 5V pin (onboard regulator) or direct 3.3V pin |
| Current Draw | ~130-180 mA active with link |
| SPI Header (2x5) | 1 NC · 2 INT · 3 RST · 4 GND · 5 5V · 6 SCLK · 7 SCS · 8 MOSI · 9 MISO · 10 3.3V |
| Connector | RJ45 magjack with link/activity LEDs |
| MAC Address | Not pre-assigned — set one in code |
Pinout Diagram
The 2x5 header carries everything: SCLK, SCS (chip select), MOSI, and MISO are the SPI bus; RST is an optional hardware reset; INT signals socket events if you want interrupt-driven code (most libraries poll instead and leave it unwired). Power enters on pin 5 (5V, through the onboard regulator) or pin 10 (regulated 3.3V directly) — use one, not both.
Wiring Guide
Arduino Wiring
| W5500 Pin | Arduino Pin | Details |
|---|---|---|
| 5V / GND | 5V / GND | Onboard regulator makes 3.3V |
| SCLK | D13 | SPI clock |
| MISO | D12 | |
| MOSI | D11 | |
| SCS | D10 | Ethernet.init(10) in code |
ESP32 Wiring
| W5500 Pin | ESP32 Pin | Details |
|---|---|---|
| 3.3V / GND | 3V3 / GND | Direct 3.3V feed (skip the 5V pin) |
| SCLK | GPIO 18 | VSPI |
| MISO | GPIO 19 | |
| MOSI | GPIO 23 | |
| SCS | GPIO 5 | Ethernet.init(5) |
Raspberry Pi Pico Wiring
| W5500 Pin | Pico Pin | Details |
|---|---|---|
| 3.3V / GND | 3V3(OUT) / GND | |
| SCLK | GP18 (SPI0 SCK) | |
| MISO | GP16 (SPI0 RX) | |
| MOSI | GP19 (SPI0 TX) | |
| SCS | GP17 | Chip select |
| RST | GP20 (optional) | Hardware reset |
Raspberry Pi (single-board) — Do You Need It?
A full Raspberry Pi already has native Ethernet, so this module isn't wired to a Pi 4/5 in practice. Where it shines in the Pi family is the microcontroller side — the Pico — or as a second isolated network path on unusual builds.
| Scenario | Recommendation |
|---|---|
| Raspberry Pi 4/5 project needs Ethernet | Use the built-in port |
| Pico project needs networking | This module + CircuitPython WIZNET5K (see Pico tab/code) |
| Pi Zero (no Ethernet) needs wired LAN | A USB-Ethernet adapter is simpler than SPI |
Code Examples
The Arduino/ESP32 sketches use the standard Ethernet library: one fetches a web page (DHCP client), one serves a live status page. The Pico examples use CircuitPython's WIZNET5K driver — install Adafruit's library bundle, or the equivalent MicroPython W5500 driver.
Arduino — DHCP + web fetch
// W5500 Ethernet - Arduino Web Client (DHCP)
// SCLK->13, MISO->12, MOSI->11, SCS->10, 5V, GND
// Library: "Ethernet" (built into the IDE)
#include <SPI.h>
#include <Ethernet.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x01 }; // pick any unique MAC
EthernetClient client;
void setup() {
Serial.begin(115200);
Ethernet.init(10); // CS pin
Serial.println("Requesting IP via DHCP...");
if (Ethernet.begin(mac) == 0) {
Serial.println("DHCP failed - check cable/router");
while (1);
}
Serial.print("IP address: ");
Serial.println(Ethernet.localIP());
if (client.connect("example.com", 80)) {
client.println("GET / HTTP/1.1");
client.println("Host: example.com");
client.println("Connection: close");
client.println();
}
}
void loop() {
while (client.available()) {
Serial.write(client.read()); // stream the response
}
if (!client.connected()) {
client.stop();
Serial.println("\n-- done --");
while (1);
}
}
ESP32 — Ethernet web server (Arduino IDE)
// W5500 Ethernet - ESP32 Web Server
// SCLK->18, MISO->19, MOSI->23, SCS->5, 3.3V, GND
#include <SPI.h>
#include <Ethernet.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x02 };
EthernetServer server(80);
unsigned long hits = 0;
void setup() {
Serial.begin(115200);
Ethernet.init(5);
if (Ethernet.begin(mac) == 0) {
Serial.println("DHCP failed");
while (1) delay(10);
}
server.begin();
Serial.print("Open http://");
Serial.println(Ethernet.localIP());
}
void loop() {
EthernetClient client = server.available();
if (!client) return;
// skip request headers
while (client.connected() && client.available()) client.read();
hits++;
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close");
client.println();
client.println("<html><body style='font-family:sans-serif'>");
client.println("<h1>ESP32 + W5500</h1>");
client.print("<p>Wired and reliable. Page hits: ");
client.print(hits);
client.print(" | Uptime: ");
client.print(millis() / 1000);
client.println(" s</p></body></html>");
delay(1);
client.stop();
}
Raspberry Pi Pico (CircuitPython) — DHCP + fetch
# W5500 Ethernet - Pico CircuitPython Example
# SCLK->GP18, MISO->GP16, MOSI->GP19, SCS->GP17, RST->GP20
# Libraries (from the Adafruit bundle, copy to /lib):
# adafruit_wiznet5k, adafruit_requests, adafruit_connection_manager
import board
import busio
import digitalio
import adafruit_connection_manager
import adafruit_requests
from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET5K
spi = busio.SPI(board.GP18, MOSI=board.GP19, MISO=board.GP16)
cs = digitalio.DigitalInOut(board.GP17)
rst = digitalio.DigitalInOut(board.GP20)
eth = WIZNET5K(spi, cs, reset=rst, is_dhcp=True)
print("IP address:", eth.pretty_ip(eth.ip_address))
print("Link up:", eth.link_status)
pool = adafruit_connection_manager.get_radio_socketpool(eth)
ssl = adafruit_connection_manager.get_radio_ssl_context(eth)
requests = adafruit_requests.Session(pool, ssl)
print("Fetching http://wifitest.adafruit.com/testwifi/index.html ...")
resp = requests.get("http://wifitest.adafruit.com/testwifi/index.html")
print("Response:", resp.text)
resp.close()
Raspberry Pi Pico — tiny status server (CircuitPython)
# W5500 Ethernet - Pico CircuitPython web server
# Same wiring/libraries as the client example.
import time
import board, busio, digitalio
from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET5K
import adafruit_wiznet5k.adafruit_wiznet5k_socketpool as socketpool
spi = busio.SPI(board.GP18, MOSI=board.GP19, MISO=board.GP16)
cs = digitalio.DigitalInOut(board.GP17)
rst = digitalio.DigitalInOut(board.GP20)
eth = WIZNET5K(spi, cs, reset=rst, is_dhcp=True)
print("Serving on http://{}".format(eth.pretty_ip(eth.ip_address)))
pool = socketpool.SocketPool(eth)
server = pool.socket()
server.bind((eth.pretty_ip(eth.ip_address), 80))
server.listen(1)
hits = 0
while True:
conn, addr = server.accept()
hits += 1
conn.recv(1024) # discard request
body = ("<html><body><h1>Pico + W5500</h1>"
"<p>Hits: {} | Uptime: {:.0f} s</p>"
"</body></html>").format(hits, time.monotonic())
conn.send(b"HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"
+ body.encode())
conn.close()