How to Build ESP32-S3 Dual Network with WiFi and W5500 Ethernet Failover?
Complete working example of ESP32-S3 with WiFi + W5500 Ethernet dual interface.
프로젝트 개요
이 프로젝트는 ESP32-S3 MCU에서 WiFi와 W5500 이더넷을 동시에 사용하여 네트워크 이중화를 구현한 프로덕션 레벨 예제입니다. 이더넷을 우선 사용하고 WiFi를 백업으로 자동 전환하는 Failover 메커니즘을 제공하여 산업용 IoT 게이트웨이와 미션 크리티컬 애플리케이션에 적합합니다.
핵심 기능:
- ✅ WiFi + 이더넷 동시 동작
- ✅ 자동 Failover (이더넷 우선, WiFi 백업)
- ✅ 비동기 연결 (Non-blocking)
- ✅ 간단한 API (상태 확인, IP 조회)
- ✅ ESP-IDF 5.x 기반 프로덕션 코드
테스트 하드웨어:
- Waveshare ESP32-S3-ETH (16MB Flash, 8MB PSRAM) ✅ 권장
- W5500 이더넷 모듈 (SPI 기반)
Repository: github.com/ahmedalalousi/esp32-community-projects
WIZnet W5500가 이 프로젝트에서 사용된 이유
네트워크 이중화의 핵심: W5500
이 프로젝트에서 W5500은 단순한 이더넷 컨트롤러 이상의 역할을 합니다. 하드웨어 TCP/IP 오프로드를 통해 ESP32-S3가 WiFi와 이더넷을 동시에 안정적으로 운영할 수 있게 합니다.
W5500 주요 특징:
- 하드웨어 TCP/IP 스택: MAC, PHY, 프로토콜 처리를 칩 내부에서 수행
- 8개 독립 소켓: 동시 다중 연결 지원
- 32 KB 내부 버퍼: 패킷 처리 전용 메모리
- SPI 인터페이스: 최대 80 MHz, ESP32-S3의 SPI2_HOST 사용
듀얼 인터페이스에서 W5500의 이점
| 측면 | WiFi 단독 | WiFi + W5500 |
|---|---|---|
| 네트워크 안정성 | RF 간섭 취약 | 유선 백업 제공 |
| 연결 지연 | 8-15 ms | 1-3 ms (이더넷) |
| MCU 부하 | WiFi 스택만 | W5500이 이더넷 처리 |
| 산업 환경 적합성 | 낮음 | 높음 |
실용적 장점:
- 공장/온실 같은 RF 노이즈 환경에서 이더넷으로 안정적 연결
- WiFi가 일시적으로 불안정해도 서비스 연속성 유지
- ESP32-S3가 WiFi와 이더넷 TCP/IP를 모두 소프트웨어로 처리할 필요 없음
시스템 아키텍처
데이터 흐름:
- 초기화: ESP32-S3가 WiFi와 W5500 이더넷을 모두 초기화
- 비동기 연결: 두 인터페이스가 독립적으로 DHCP 수행
- 우선순위 선택:
network_get_active_interface()가 이더넷 우선 반환 - Failover: 이더넷 끊김 시 WiFi로 자동 전환
핵심 구현 코드
W5500 SPI 설정
// sdkconfig.defaults에서 자동 설정
CONFIG_ETH_SPI_ETHERNET_W5500=y
CONFIG_ETH_SPI_HOST=2 // SPI2_HOST
CONFIG_ETH_SPI_SCLK_GPIO=13
CONFIG_ETH_SPI_MOSI_GPIO=11
CONFIG_ETH_SPI_MISO_GPIO=12
CONFIG_ETH_SPI_CS_GPIO=14
CONFIG_ETH_SPI_INT_GPIO=10
CONFIG_ETH_SPI_RST_GPIO=9
CONFIG_ETH_SPI_CLOCK_MHZ=20 // 20 MHz SPI 클럭
네트워크 API 사용 예제
#include "network.h"
void app_main(void) {
// 1. 초기화
ESP_ERROR_CHECK(network_init());
// 2. 연결 시작 (비동기)
ESP_ERROR_CHECK(network_start());
// 3. 상태 확인
if (network_is_connected(NETWORK_IF_ETHERNET)) {
const char* eth_ip = network_get_ip(NETWORK_IF_ETHERNET);
ESP_LOGI(TAG, "Ethernet IP: %s", eth_ip);
}
if (network_is_connected(NETWORK_IF_WIFI)) {
const char* wifi_ip = network_get_ip(NETWORK_IF_WIFI);
ESP_LOGI(TAG, "WiFi IP: %s", wifi_ip);
}
// 4. 현재 활성 인터페이스 확인
network_interface_t active = network_get_active_interface();
ESP_LOGI(TAG, "Active: %s",
active == NETWORK_IF_ETHERNET ? "Ethernet" : "WiFi");
}
빠른 시작 가이드
1단계: 하드웨어 연결
ESP32-S3 ↔ W5500 배선:
| W5500 | ESP32-S3 GPIO | 기능 |
|---|---|---|
| MOSI | GPIO 11 | SPI MOSI |
| MISO | GPIO 12 | SPI MISO |
| SCLK | GPIO 13 | SPI Clock (20 MHz) |
| CS | GPIO 14 | Chip Select |
| INT | GPIO 10 | Interrupt (선택) |
| RST | GPIO 9 | Reset |
| VCC | 3.3V | 5V 금지! |
| GND | GND | 공통 접지 |
2단계: ESP-IDF 설치
# ESP-IDF v5.0 이상 필요
git clone --recursive https://github.com/espressif/esp-idf.git
cd esp-idf
git checkout v5.5.1
./install.sh esp32s3
. ./export.sh
3단계: 프로젝트 빌드
git clone https://github.com/ahmedalalousi/esp32-community-projects.git
cd esp32-community-projects
idf.py set-target esp32s3
idf.py menuconfig
# WiFi Configuration에서 SSID/비밀번호 설정
idf.py build
idf.py -p /dev/ttyUSB0 flash monitor
4단계: 동작 확인
I (xxx) NETWORK: WiFi connected to AP
I (xxx) NETWORK: ✓ WiFi got IP: 192.168.1.100
I (xxx) NETWORK: Ethernet link up
I (xxx) NETWORK: ✓ Ethernet got IP: 192.168.1.101
I (xxx) MAIN: Active: Ethernet
실제 사용 사례
1. 산업용 IoT 게이트웨이
환경: 공장 바닥, 금속 구조물이 많아 WiFi 불안정
구성:
- 이더넷: 주 연결 (안정적)
- WiFi: 백업 연결 (이더넷 장애 시)
- 센서: Modbus/RS485로 연결
- 클라우드: MQTT over 이더넷
효과: 네트워크 다운타임 99% 감소
2. 스마트 빌딩 컨트롤러
환경: 지하 주차장, WiFi 신호 약함
// 층별 센서 데이터 수집
void collect_sensor_data() {
if (network_is_connected(NETWORK_IF_ETHERNET)) {
send_via_ethernet(); // 빠른 전송
} else {
send_via_wifi(); // Failover
}
}
효과: 안정적인 실시간 모니터링
3. 원격 카메라/NVR 시스템
환경: 옥외 설치, WiFi 간헐적 끊김
우선순위:
1. 이더넷 (PoE 전원 + 데이터)
2. WiFi (이더넷 케이블 손상 시)
효과: 영상 스트리밍 끊김 방지
주요 설정 파일
sdkconfig.defaults (핵심 설정)
# ESP32-S3 타겟
CONFIG_IDF_TARGET="esp32s3"
# Flash/PSRAM (Waveshare ESP32-S3-ETH 기준)
CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y
CONFIG_SPIRAM_MODE_OCT=y
# W5500 이더넷
CONFIG_ETH_ENABLED=y
CONFIG_ETH_USE_SPI_ETHERNET=y
CONFIG_ETH_SPI_ETHERNET_W5500=y
# SPI 핀 설정
CONFIG_ETH_SPI_HOST=2
CONFIG_ETH_SPI_SCLK_GPIO=13
CONFIG_ETH_SPI_MOSI_GPIO=11
CONFIG_ETH_SPI_MISO_GPIO=12
CONFIG_ETH_SPI_CS_GPIO=14
CONFIG_ETH_SPI_INT_GPIO=10
CONFIG_ETH_SPI_RST_GPIO=9
CONFIG_ETH_SPI_CLOCK_MHZ=20
# PHY 설정
CONFIG_ETH_PHY_ADDR=1
중요: 이 파일 덕분에 menuconfig에서 이더넷 설정 불필요. WiFi 자격증명만 입력하면 됨.
FAQ
Q1. 왜 WiFi와 이더넷을 동시에 사용하나요?
네트워크 이중화를 위해서입니다. 주요 이점:
- 안정성: 한 인터페이스 장애 시 자동 전환
- 산업 환경: WiFi가 불안정한 공장/온실에서 유선 백업
- 지연 시간: 이더넷 우선 사용 (1-3 ms vs WiFi 8-15 ms)
- 연속성: 네트워크 다운타임 최소화
사용 사례: 미션 크리티컬 IoT 게이트웨이, 산업 자동화, 원격 모니터링
Q2. W5500을 선택한 이유는 무엇인가요?
W5500의 하드웨어 TCP/IP 오프로드가 핵심입니다.
장점:
- ESP32-S3가 WiFi 스택만 처리, 이더넷은 W5500이 담당
- MCU RAM 절약 (~30 KB)
- CPU 오버헤드 감소 (15-20%)
- 듀얼 인터페이스 구현 단순화
대안 비교:
- LAN8720 (RMII): ESP32-S3가 TCP/IP 스택 처리 필요, 듀얼 인터페이스 부담
- WiFi 단독: RF 간섭 취약, 백업 없음
Q3. 어떤 하드웨어가 필요한가요?
최소 구성:
- ✅ ESP32-S3 개발 보드 (16MB Flash 권장)
- ✅ W5500 이더넷 모듈
- ✅ 점퍼 와이어 (SPI 연결)
- ✅ 이더넷 케이블
권장 보드:
- Waveshare ESP32-S3-ETH (W5500 내장, PoE 지원)
- LilyGo T-ETH-Lite ESP32-S3
중요: W5500 모듈 전원은 3.3V입니다. 5V 인가 시 손상 가능.
Q4. Failover는 어떻게 작동하나요?
우선순위 로직:
network_interface_t network_get_active_interface(void) {
// 1. 이더넷 우선
if (s_eth_connected) {
return NETWORK_IF_ETHERNET;
}
// 2. WiFi로 Failover
else if (s_wifi_connected) {
return NETWORK_IF_WIFI;
}
// 3. 둘 다 끊김
return NETWORK_IF_NONE;
}
동작 시나리오:
- 정상: 이더넷 사용 (192.168.1.101)
- 이더넷 케이블 뽑힘: 자동으로 WiFi 전환 (192.168.1.100)
- 이더넷 복구: 다시 이더넷으로 전환
전환 시간: ~2-5초 (DHCP 재협상)
Q5. ESP-IDF 버전 호환성은?
테스트 완료:
- ✅ ESP-IDF v5.0, v5.1, v5.2, v5.3
- ✅ ESP-IDF v5.5.1 (최신 안정 버전)
권장: v5.5.1 사용
알려진 이슈:
- ⚠️ ESP-IDF v4.x: W5500 드라이버 버그 있음
Q6. 정적 IP를 사용할 수 있나요?
예, 가능합니다. 이 예제는 DHCP를 사용하지만, ESP-IDF API로 정적 IP 설정 가능합니다.
정적 IP 설정 예제:
// WiFi 정적 IP
esp_netif_ip_info_t ip_info;
IP4_ADDR(&ip_info.ip, 192, 168, 1, 100);
IP4_ADDR(&ip_info.gw, 192, 168, 1, 1);
IP4_ADDR(&ip_info.netmask, 255, 255, 255, 0);
esp_netif_set_ip_info(wifi_netif, &ip_info);
// 이더넷 정적 IP
IP4_ADDR(&ip_info.ip, 192, 168, 1, 101);
esp_netif_set_ip_info(eth_netif, &ip_info);
참고: network.c 수정 필요
Q7. 이 코드를 프로덕션에 사용할 수 있나요?
예, 프로덕션 준비 완료입니다.
프로덕션 품질 요소:
- ✅ 에러 핸들링 완비
- ✅ 이벤트 기반 비동기 연결
- ✅ 깔끔한 API 설계
- ✅ 상세한 로깅
- ✅ 실전 테스트 완료 (Waveshare ESP32-S3-ETH)
주의 사항:
- 보안: TLS/SSL 추가 권장
- 모니터링: Watchdog 타이머 구현
- OTA: 펌웨어 업데이트 메커니즘 추가
기술 사양
W5500 상세 스펙
| 항목 | 사양 |
|---|---|
| 프로토콜 | TCP, UDP, ICMP, IPv4, ARP, IGMP, PPPoE |
| 소켓 | 8개 독립 하드웨어 소켓 |
| 버퍼 | 32 KB 내부 TX/RX 메모리 |
| 인터페이스 | SPI (최대 80 MHz) |
| 속도 | 10/100 Mbps Ethernet |
| 전원 | 3.3V, ~132 mA (100 Mbps 링크) |
| 특수 기능 | Wake-on-LAN, Auto-negotiation |
ESP32-S3 리소스 사용
| 항목 | 사용량 | 비고 |
|---|---|---|
| RAM | ~50 KB | WiFi + 이더넷 스택 |
| Flash | ~1.2 MB | 펌웨어 + ESP-IDF |
| CPU (평균) | 10-15% | 네트워크 처리 |
| GPIO | 8개 | WiFi(내장) + W5500(SPI) |
프로젝트 구조
esp32-community-projects/
├── CMakeLists.txt # 최상위 빌드 설정
├── sdkconfig.defaults # W5500 핀 설정 포함
├── main/
│ ├── CMakeLists.txt # 컴포넌트 빌드 설정
│ ├── Kconfig.projbuild # WiFi 자격증명 메뉴
│ ├── main.c # 애플리케이션 진입점
│ ├── network.c # 듀얼 인터페이스 구현
│ └── network.h # 네트워크 API 헤더
└── doc/ # 문서 (배선도 등)
Project Overview
This project implements a production-ready dual network interface on ESP32-S3, combining WiFi and W5500 Ethernet with automatic failover. It prioritizes Ethernet for stable connectivity and falls back to WiFi when needed, making it ideal for industrial IoT gateways and mission-critical applications.
Key Features:
- ✅ Simultaneous WiFi + Ethernet operation
- ✅ Automatic failover (Ethernet priority, WiFi backup)
- ✅ Non-blocking asynchronous connections
- ✅ Simple API (status check, IP query)
- ✅ Production-grade ESP-IDF 5.x code
Tested Hardware:
- Waveshare ESP32-S3-ETH (16MB Flash, 8MB PSRAM) ✅ Recommended
- W5500 Ethernet Module (SPI-based)
Repository: github.com/ahmedalalousi/esp32-community-projects
Why WIZnet W5500 in This Project
The Core of Network Redundancy: W5500
In this project, W5500 is more than just an Ethernet controller. Its hardware TCP/IP offload enables ESP32-S3 to reliably operate WiFi and Ethernet simultaneously.
W5500 Key Features:
- Hardware TCP/IP Stack: Handles MAC, PHY, and protocol processing internally
- 8 Independent Sockets: Supports simultaneous multiple connections
- 32 KB Internal Buffer: Dedicated packet processing memory
- SPI Interface: Up to 80 MHz, uses ESP32-S3's SPI2_HOST
W5500 Advantages in Dual Interface
| Aspect | WiFi Only | WiFi + W5500 |
|---|---|---|
| Network Stability | Vulnerable to RF interference | Wired backup available |
| Connection Latency | 8-15 ms | 1-3 ms (Ethernet) |
| MCU Load | WiFi stack only | W5500 handles Ethernet |
| Industrial Suitability | Low | High |
Practical Benefits:
- Stable Ethernet connection in RF-noisy environments (factories/greenhouses)
- Service continuity maintained even when WiFi is temporarily unstable
- ESP32-S3 doesn't need to handle both WiFi and Ethernet TCP/IP in software
System Architecture
Data Flow:
- Initialization: ESP32-S3 initializes both WiFi and W5500 Ethernet
- Async Connection: Both interfaces perform DHCP independently
- Priority Selection:
network_get_active_interface()returns Ethernet first - Failover: Automatically switches to WiFi if Ethernet disconnects
Core Implementation
W5500 SPI Configuration
// Auto-configured in sdkconfig.defaults
CONFIG_ETH_SPI_ETHERNET_W5500=y
CONFIG_ETH_SPI_HOST=2 // SPI2_HOST
CONFIG_ETH_SPI_SCLK_GPIO=13
CONFIG_ETH_SPI_MOSI_GPIO=11
CONFIG_ETH_SPI_MISO_GPIO=12
CONFIG_ETH_SPI_CS_GPIO=14
CONFIG_ETH_SPI_INT_GPIO=10
CONFIG_ETH_SPI_RST_GPIO=9
CONFIG_ETH_SPI_CLOCK_MHZ=20 // 20 MHz SPI clock
Network API Usage Example
#include "network.h"
void app_main(void) {
// 1. Initialize
ESP_ERROR_CHECK(network_init());
// 2. Start connections (async)
ESP_ERROR_CHECK(network_start());
// 3. Check status
if (network_is_connected(NETWORK_IF_ETHERNET)) {
const char* eth_ip = network_get_ip(NETWORK_IF_ETHERNET);
ESP_LOGI(TAG, "Ethernet IP: %s", eth_ip);
}
if (network_is_connected(NETWORK_IF_WIFI)) {
const char* wifi_ip = network_get_ip(NETWORK_IF_WIFI);
ESP_LOGI(TAG, "WiFi IP: %s", wifi_ip);
}
// 4. Get active interface
network_interface_t active = network_get_active_interface();
ESP_LOGI(TAG, "Active: %s",
active == NETWORK_IF_ETHERNET ? "Ethernet" : "WiFi");
}
Quick Start Guide
Step 1: Hardware Wiring
ESP32-S3 ↔ W5500 Connections:
| W5500 | ESP32-S3 GPIO | Function |
|---|---|---|
| MOSI | GPIO 11 | SPI MOSI |
| MISO | GPIO 12 | SPI MISO |
| SCLK | GPIO 13 | SPI Clock (20 MHz) |
| CS | GPIO 14 | Chip Select |
| INT | GPIO 10 | Interrupt (optional) |
| RST | GPIO 9 | Reset |
| VCC | 3.3V | No 5V! |
| GND | GND | Common ground |
Step 2: Install ESP-IDF
# ESP-IDF v5.0 or later required
git clone --recursive https://github.com/espressif/esp-idf.git
cd esp-idf
git checkout v5.5.1
./install.sh esp32s3
. ./export.sh
Step 3: Build Project
git clone https://github.com/ahmedalalousi/esp32-community-projects.git
cd esp32-community-projects
idf.py set-target esp32s3
idf.py menuconfig
# Set SSID/Password in WiFi Configuration
idf.py build
idf.py -p /dev/ttyUSB0 flash monitor
Step 4: Verify Operation
I (xxx) NETWORK: WiFi connected to AP
I (xxx) NETWORK: ✓ WiFi got IP: 192.168.1.100
I (xxx) NETWORK: Ethernet link up
I (xxx) NETWORK: ✓ Ethernet got IP: 192.168.1.101
I (xxx) MAIN: Active: Ethernet
Real-World Use Cases
1. Industrial IoT Gateway
Environment: Factory floor with metal structures, unstable WiFi
Configuration:
- Ethernet: Primary connection (stable)
- WiFi: Backup connection (Ethernet failure)
- Sensors: Connected via Modbus/RS485
- Cloud: MQTT over Ethernet
Result: 99% reduction in network downtime
2. Smart Building Controller
Environment: Underground parking, weak WiFi signal
// Floor-by-floor sensor data collection
void collect_sensor_data() {
if (network_is_connected(NETWORK_IF_ETHERNET)) {
send_via_ethernet(); // Fast transmission
} else {
send_via_wifi(); // Failover
}
}
Result: Stable real-time monitoring
3. Remote Camera/NVR System
Environment: Outdoor installation, intermittent WiFi
Priority:
1. Ethernet (PoE power + data)
2. WiFi (if Ethernet cable damaged)
Result: Prevents video streaming interruptions
Frequently Asked Questions
Q1. Why use both WiFi and Ethernet simultaneously?
For network redundancy. Key benefits:
- Reliability: Automatic failover on interface failure
- Industrial: Wired backup in unstable WiFi environments (factories/greenhouses)
- Latency: Ethernet priority (1-3 ms vs WiFi 8-15 ms)
- Continuity: Minimizes network downtime
Use cases: Mission-critical IoT gateways, industrial automation, remote monitoring
Q2. Why choose W5500?
W5500's hardware TCP/IP offload is the key.
Advantages:
- ESP32-S3 only handles WiFi stack, W5500 manages Ethernet
- MCU RAM savings (~30 KB)
- Reduced CPU overhead (15-20%)
- Simplifies dual interface implementation
Alternative comparison:
- LAN8720 (RMII): ESP32-S3 must handle TCP/IP stack, dual interface burden
- WiFi only: Vulnerable to RF interference, no backup
Q3. What hardware is required?
Minimum configuration:
- ✅ ESP32-S3 development board (16MB Flash recommended)
- ✅ W5500 Ethernet module
- ✅ Jumper wires (SPI connection)
- ✅ Ethernet cable
Recommended boards:
- Waveshare ESP32-S3-ETH (W5500 built-in, PoE support)
- LilyGo T-ETH-Lite ESP32-S3
Important: W5500 module power is 3.3V. 5V will damage the chip.
Q4. How does failover work?
Priority logic:
network_interface_t network_get_active_interface(void) {
// 1. Ethernet priority
if (s_eth_connected) {
return NETWORK_IF_ETHERNET;
}
// 2. Failover to WiFi
else if (s_wifi_connected) {
return NETWORK_IF_WIFI;
}
// 3. Both disconnected
return NETWORK_IF_NONE;
}
Operating scenario:
- Normal: Uses Ethernet (192.168.1.101)
- Ethernet cable unplugged: Auto-switches to WiFi (192.168.1.100)
- Ethernet restored: Switches back to Ethernet
Switchover time: ~2-5 seconds (DHCP renegotiation)
Q5. ESP-IDF version compatibility?
Tested:
- ✅ ESP-IDF v5.0, v5.1, v5.2, v5.3
- ✅ ESP-IDF v5.5.1 (latest stable)
Recommended: Use v5.5.1
Known issues:
- ⚠️ ESP-IDF v4.x: W5500 driver bugs
Q6. Can I use static IP?
Yes, possible. This example uses DHCP, but ESP-IDF API supports static IP configuration.
Static IP example:
// WiFi static IP
esp_netif_ip_info_t ip_info;
IP4_ADDR(&ip_info.ip, 192, 168, 1, 100);
IP4_ADDR(&ip_info.gw, 192, 168, 1, 1);
IP4_ADDR(&ip_info.netmask, 255, 255, 255, 0);
esp_netif_set_ip_info(wifi_netif, &ip_info);
// Ethernet static IP
IP4_ADDR(&ip_info.ip, 192, 168, 1, 101);
esp_netif_set_ip_info(eth_netif, &ip_info);
Note: Requires network.c modification
Q7. Is this code production-ready?
Yes, production-ready.
Production quality elements:
- ✅ Complete error handling
- ✅ Event-driven async connections
- ✅ Clean API design
- ✅ Detailed logging
- ✅ Field-tested (Waveshare ESP32-S3-ETH)
Considerations:
- Security: TLS/SSL addition recommended
- Monitoring: Implement watchdog timer
- OTA: Add firmware update mechanism
Technical Specifications
W5500 Detailed Specs
| Item | Specification |
|---|---|
| Protocols | TCP, UDP, ICMP, IPv4, ARP, IGMP, PPPoE |
| Sockets | 8 independent hardware sockets |
| Buffer | 32 KB internal TX/RX memory |
| Interface | SPI (up to 80 MHz) |
| Speed | 10/100 Mbps Ethernet |
| Power | 3.3V, ~132 mA (100 Mbps link) |
| Special Features | Wake-on-LAN, Auto-negotiation |
ESP32-S3 Resource Usage
| Item | Usage | Notes |
|---|---|---|
| RAM | ~50 KB | WiFi + Ethernet stacks |
| Flash | ~1.2 MB | Firmware + ESP-IDF |
| CPU (avg) | 10-15% | Network processing |
| GPIO | 8 pins | WiFi(built-in) + W5500(SPI) |
