To connect an Arduino to a wired Local Area Network (LAN), the most reliable and resource-efficient method is using a Wiznet W5500 Ethernet module via the SPI bus. Unlike older modules that force the microcontroller to process TCP/IP packets in software, the W5500 handles the entire network stack in dedicated silicon. This guide covers the exact wiring, pin mapping, and complete DHCP web server code required to get your Arduino LAN connection running on the bench, along with the specific debugging steps for when the link fails to negotiate.
Hardware Selection: Why W5500 Wins for Arduino LAN
When builders search for an Arduino LAN solution, they typically encounter three hardware paths. Choosing the wrong one leads to exhausted RAM, dropped packets, or unnecessary WiFi complexity. The W5500 is the definitive choice for wired embedded projects in 2026.
| Module / Chip | TCP/IP Stack | RAM Overhead | SPI Speed | Verdict |
|---|---|---|---|---|
| Wiznet W5500 | Hardware (Offloaded) | < 1 KB (Socket buffers) | Up to 80 MHz | Best Choice. Stable, fast, leaves MCU RAM free for sensors. |
| ENC28J60 | Software (UIPEthernet) | ~1.5 KB (Heavy) | 10 MHz max | Avoid. Obsolete, drops packets under load, eats Uno RAM. |
| ESP32 (Built-in WiFi) | Hardware (LwIP) | ~40 KB (WiFi stack) | N/A (Wireless) | Use for WiFi. Not suitable if physical LAN isolation is required. |
The W5500 supports up to 8 simultaneous hardware sockets, meaning your Arduino can run a web server, an MQTT client, and an NTP time-sync request concurrently without breaking a sweat. For authoritative protocol details, refer to the official Wiznet W5500 datasheet and product page.
Parts List and SPI Pin Mapping
Before wiring, ensure you have the correct module variant. The market is flooded with mislabeled boards. You need the W5500 Mini Module (Black PCB). The green PCB modules are almost always ENC28J60 chips mislabeled by overseas sellers.
Required Parts
- MCU: Arduino Uno R4 Minima (Target board for this guide)
- Ethernet: Wiznet W5500 Mini Module (Black PCB with onboard 3.3V LDO)
- Wiring: 6x Female-to-Male Dupont jumper wires (minimum 22 AWG)
- Network: Cat5e or Cat6 Ethernet patch cable, connected to a DHCP-enabled router/switch
SPI Pin Mapping Table
The Arduino Uno R4 Minima uses the standard ATmega SPI bus pins. The W5500 requires a Chip Select (CS) and a hardware Reset pin to initialize correctly.
| W5500 Module Pin | Arduino Uno R4 Minima Pin | Function / Notes |
|---|---|---|
| VCC | 5V | Module has onboard LDO to step down to 3.3V logic. |
| GND | GND | Common ground reference. |
| MOSI | D11 | Master Out, Slave In (SPI Data to W5500). |
| MISO | D12 | Master In, Slave Out (SPI Data from W5500). |
| SCK | D13 | Serial Clock (SPI timing). |
| CS (or SCS) | D10 | Chip Select. Must be pulled HIGH when idle. |
| RST | D9 | Hardware Reset. Active LOW. |
Complete DHCP Web Server Code
This code targets the Arduino Uno R4 Minima using the standard Arduino Ethernet library, which natively supports the W5500 in modern IDE versions. It includes a hardware reset sequence (crucial for W5500 stability) and a static IP fallback if DHCP fails. For library specifics, consult the Arduino Ethernet Library Documentation.
#include <SPI.h>
#include <Ethernet.h>
// --- PIN DEFINITIONS ---
#define CS_PIN 10
#define RESET_PIN 9
// MAC Address (Use a unique one on your LAN; avoid conflicts)
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// Fallback Static IP configuration if DHCP fails
IPAddress fallbackIP(192, 168, 1, 177);
IPAddress fallbackDNS(192, 168, 1, 1);
IPAddress fallbackGateway(192, 168, 1, 1);
IPAddress fallbackSubnet(255, 255, 255, 0);
EthernetServer server(80);
void setup() {
Serial.begin(115200);
while (!Serial) { delay(10); } // Wait for serial port (Uno R4 native USB)
// Configure SPI control pins
pinMode(CS_PIN, OUTPUT);
pinMode(RESET_PIN, OUTPUT);
digitalWrite(CS_PIN, HIGH); // Deselect W5500 initially
// Hardware reset sequence (Required for W5500 to clear stale registers)
digitalWrite(RESET_PIN, LOW);
delay(50);
digitalWrite(RESET_PIN, HIGH);
delay(150); // Wait for W5500 internal PLL to lock
Serial.println("Initializing Arduino LAN via W5500...");
// Tell the Ethernet library which pin is CS
Ethernet.init(CS_PIN);
// Attempt DHCP
if (Ethernet.begin(mac) == 0) {
Serial.println("ERROR: Failed to configure Ethernet using DHCP");
Serial.println("Applying Fallback Static IP...");
Ethernet.begin(mac, fallbackIP, fallbackDNS, fallbackGateway, fallbackSubnet);
}
Serial.print("LAN IP Address: ");
Serial.println(Ethernet.localIP());
server.begin();
}
void loop() {
EthernetClient client = server.available();
if (client) {
Serial.println("New client connected");
String currentLine = "";
while (client.connected()) {
if (client.available()) {
char c = client.read();
Serial.write(c);
if (c == '\n') {
if (currentLine.length() == 0) {
// HTTP Response Headers
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println();
// HTML Body
client.println("<h1>Arduino LAN Web Server</h1>");
client.print("Uptime (ms): ");
client.println(millis());
client.println("<br><a href=\"/\">Refresh</a>");
client.println(); // End HTTP response
break;
} else {
currentLine = "";
}
} else if (c != '\r') {
currentLine += c;
}
}
}
client.stop();
Serial.println("Client disconnected.");
}
}
Debugging: First Three Things to Check on Failure
Wired Ethernet on microcontrollers rarely fails silently; it usually throws specific errors in the serial monitor. If your Arduino LAN connection drops or fails to initialize, follow this ranked diagnostic path.
Error 1: "ERROR: Failed to configure Ethernet using DHCP"
This exact string triggers when Ethernet.begin(mac) returns 0. The physical link might be up, but the IP negotiation failed.
- Check the physical link LEDs: Look at the RJ45 jack on the W5500. Are the green (link) and yellow (activity) LEDs lit? If dark, your switch port is dead, the cable is broken, or the module's magnetics are fried.
- Verify DHCP Server Availability: Ensure the router port you are plugged into actually hands out DHCP addresses. Some enterprise switch ports are locked to specific MAC addresses or require 802.1X authentication, which the W5500 cannot perform.
- Check the MAC Address: If you have multiple Arduinos on the same LAN, ensure they do not share the same hardcoded MAC address (
0xDE, 0xAD...). IP conflicts will cause immediate DHCP rejection.
Error 2: "Ethernet.hardwareStatus() == EthernetNoHardware"
If you add a hardware check to your setup and get this, the MCU cannot communicate with the W5500 chip over SPI at all.
- Missing
Ethernet.init(CS_PIN): The standard Arduino Ethernet library defaults to CS pin 4 or 53 depending on the board. If you don't explicitly declareEthernet.init(10)before callingEthernet.begin(), the library will talk to the wrong pin. - SPI Wiring Reversal: MISO and MOSI are the most commonly swapped pins. MISO on the module must go to MISO (D12) on the Uno. If swapped, the MCU sends data but receives nothing.
- Logic Level Mismatch: If you are using a 5V Arduino (like the Uno R3) with a raw W5500 chip (not the black mini module with the LDO), the 5V SPI signals will backfeed into the 3.3V W5500, permanently damaging the silicon. Always use the black mini module with the onboard voltage regulator for 5V boards.
Extending and Simplifying the Build
Once your baseline Arduino LAN connection is stable, you can adapt the architecture to fit your specific project constraints.
How to Simplify: Static IP Only
If your project lives on an isolated machine-to-machine (M2M) network without a router, DHCP is a liability. It adds a 5-to-10-second timeout to your boot sequence while the W5500 broadcasts discovery packets. To simplify, delete the if (Ethernet.begin(mac) == 0) logic entirely and force a static IP immediately:
Ethernet.begin(mac, IPAddress(10, 0, 0, 50), IPAddress(10, 0, 0, 1), IPAddress(10, 0, 0, 1), IPAddress(255, 255, 255, 0));
This reduces network boot time to under 200 milliseconds.
How to Extend: Adding MQTT and NTP
The W5500's 8 hardware sockets allow you to run parallel protocols. To extend this build into an IoT sensor node:
- MQTT: Install the
PubSubClientlibrary. Pass theEthernetClientobject to the MQTT client instead of a WiFi client. The W5500 will handle the TCP keep-alives in hardware. - NTP Time Sync: Use the
NTPClientlibrary over a UDP socket. Because the W5500 handles UDP natively, you won't experience the blocking delays common with software-based ENC28J60 implementations.
By anchoring your project to the W5500 and respecting the SPI initialization sequence, your Arduino LAN deployment will achieve the same rock-solid uptime as commercial PLCs, without the industrial price tag.






