Wiznet makers

scott

Published May 18, 2026 ©

125 UCC

20 WCC

45 VAR

0 Contests

0 Followers

0 Following

Original Link

ESP32-S3-Gateway

From RS-485 to NMEA 2000 — Building a Multi-Protocol Gateway with ESP32-S3 and W5500

COMPONENTS Hardware components

WIZnet - W5500

x 1


PROJECT DESCRIPTION

요약

ESP32-S3-Gateway는 RS-485 기반 레거시 계측 장비를 Modbus TCP, UDP, NMEA 2000 세 가지 현대 프로토콜로 동시에 변환하는 오픈소스 펌웨어 게이트웨이입니다. W5500 SPI 이더넷 모듈이 산업용 유선 데이터 트래픽을 전담하고, ESP32-S3 내장 WiFi는 웹 기반 설정 및 모니터링 전용으로 분리된 이중 네트워크 구조가 핵심 설계 포인트입니다. 리플래싱 없이 브라우저에서 전체 파라미터를 런타임으로 변경할 수 있어, 산업 현장과 선박 환경 모두에서 실용적인 레거시 연동 솔루션으로 주목할 만합니다.


개요

산업 현장과 선박에는 RS-485 시리얼 버스 기반의 레거시 장비가 여전히 광범위하게 운용되고 있습니다. Modbus RTU 방식의 센서·계측기나 NMEA 0183 기반의 항법 장비는 수십 년간 검증된 신뢰성을 갖추고 있지만, 현대 네트워크 인프라와의 직접 통신은 불가능합니다. 이를 해결하기 위해 고가의 상용 게이트웨이를 도입하거나 장비 전체를 교체하는 경우가 많습니다.

ESP32-S3-Gateway는 이 간극을 저비용 오픈소스 방식으로 메우는 펌웨어 프로젝트입니다. ESP32-S3와 W5500 이더넷 모듈, CAN 트랜시버, RS-485 트랜시버를 조합하여 Modbus RTU → Modbus TCP/UDP 변환NMEA 0183 → NMEA 2000 변환을 단일 장치에서 구현합니다. 입력 모드(Modbus RTU Master / NMEA 0183 Listener)와 출력 대상은 웹 UI를 통해 런타임에 자유롭게 구성할 수 있습니다.


아키텍처

시스템은 크게 RS-485 입력 레이어, 레지스터 캐시, 멀티 프로토콜 출력 레이어 세 부분으로 구성됩니다.

데이터 흐름:

  • RS-485 기기를 폴링(기본 1초 주기)하여 레지스터 캐시를 갱신
  • 캐시 데이터를 W5500 이더넷 경유 Modbus TCP 서버(포트 502)와 UDP 브로드캐스트(기본 2초 주기)로 동시 제공
  • 동일 캐시에서 NMEA 2000 PGN을 생성하여 CAN 백본으로 송출(기본 1초 주기)
  • WiFi 인터페이스는 데이터 트래픽과 완전 분리, 설정·모니터링 전용으로 동작

지원 프로토콜 상세

입력 프로토콜 (선택적 운용)

모드프로토콜역할
Mode 0Modbus RTU Master최대 8개 슬레이브 순차 폴링, 슬레이브당 최대 64 레지스터
Mode 1NMEA 0183 ListenerHeading / Depth / Speed / Position 문장 파싱

두 모드는 동일한 RS-485 물리 핀을 공유하며, 웹 UI에서 런타임 전환 가능합니다.

출력 프로토콜 (동시 운용)

  • Modbus TCP Server: FC03(Read Holding) / FC04(Read Input), 동시 최대 4클라이언트. Unit ID 라우팅 또는 플랫 주소 방식 선택 가능
  • UDP 브로드캐스트: JSON 포맷(ts, slaves[], id, valid, regs[]), 주기 및 포트 설정 가능
  • NMEA 2000: PGN 127250(선수각), 128267(수심), 128259(선속), 129025(위치) 4종 송출

W5500 이중 네트워크 구조

📷 [이미지 필요: 이중 네트워크 구조 개념도 (WiFi vs W5500 Ethernet 역할 분리)] → 원본 이미지 URL: 공식 이미지 미확인

이 프로젝트에서 W5500은 단순한 이더넷 연결 수단이 아닌, 산업용 데이터 경로의 전담 처리 장치로 설계되었습니다.

네트워크 역할 분리 구조:

  • WiFi (ESP32-S3 내장): 관리 전용 인터페이스. 웹 UI 서빙, REST API, 레지스터 실시간 모니터링 담당. 현장 엔지니어의 설정 접근 경로
  • W5500 Ethernet: 데이터 전용 인터페이스. Modbus TCP 서버(포트 502)와 UDP 브로드캐스트를 독립 IP로 제공. SCADA, PLC, 데이터 수집 시스템이 연결되는 경로

두 인터페이스는 서로 다른 IP 주소를 가지며 물리적으로 분리됩니다. 예를 들어 WiFi는 192.168.1.55, W5500 Ethernet은 192.168.1.56으로 각각 운용됩니다.

W5500의 하드와이어드 TCP/IP 역할:

arduino-libraries/Ethernet 라이브러리를 통해 W5500 온칩 하드와이어드 TCP/IP 스택을 직접 활용합니다. ESP32가 W5500의 소켓 레지스터를 SPI로 제어하면, TCP 연결 관리·패킷 처리·재조합은 W5500 내부에서 완결됩니다. 그 결과:

  • ESP32 MCU 부하 감소: TCP/IP 처리가 W5500으로 오프로딩되어 ESP32는 프로토콜 변환 로직과 NMEA 2000 생성에 집중
  • 결정론적 네트워크 응답: 소프트웨어 TCP/IP 스택 대비 처리 지연 변동이 적음
  • 동시 4클라이언트 지원: W5500의 8소켓 중 4소켓을 Modbus TCP 연결에 할당

Web UI와 런타임 설정

운용 유연성 측면에서 이 프로젝트의 두드러진 특징 중 하나는 완전한 런타임 설정 구조입니다.

  • 초기 부팅: WiFi 자격증명 미저장 시 소프트 AP(ESP32-Gateway / config1234) 자동 생성 → 브라우저에서 바로 설정 시작
  • 설정 범위: RS-485 모드 전환, 슬레이브 ID 목록, 레지스터 범위, 폴링 주기, TCP/UDP 포트, NMEA 2000 레지스터 매핑, W5500 정적 IP — 전 항목 웹 UI에서 변경 가능
  • 저장 방식: 모든 설정은 ESP32 NVS에 영속 저장, 전원 재투입 후에도 유지
  • REST API: /api/config (GET/POST), /api/regs (GET), /api/reset (POST) — 외부 시스템에서 자동화된 설정 관리 가능
  • 라이브 레지스터 모니터: 웹 UI 하단에서 2초 주기로 전체 레지스터 값 실시간 확인

기술 특징

레지스터 캐시 기반 멀티 클라이언트 대응:

RS-485 폴링 결과를 RAM 캐시에 유지하고, 복수의 클라이언트(Modbus TCP, UDP, NMEA 2000)가 동일 캐시를 참조합니다. 이 구조 덕분에 RS-485 폴링과 TCP 응답이 디커플링되어 다수의 클라이언트에 일관된 응답 속도를 제공합니다.

Unit ID 라우팅 / 플랫 주소 이중 지원:

  • Unit ID 라우팅: Modbus TCP 클라이언트의 Unit ID = RS-485 슬레이브 ID → 레지스터 오프셋 0~63 직접 참조
  • 플랫 주소: Unit ID 0x00 / 0xFF → (slave_id - 1) × 64 + reg_index 방식으로 전체 슬레이브 공간 단일 주소화

NMEA 2000 자동 생성: 레지스터 캐시의 인덱스와 단위 스케일을 매핑하여 4종의 PGN을 자동 생성합니다. 예를 들어 Heading 레지스터 값 1234×0.1123.4°로 변환 후 PGN 127250으로 송출합니다. 슬레이브 데이터의 valid 플래그가 false인 경우 PGN 송출은 중단됩니다.


비즈니스 가치 및 활용 시나리오

레거시 RS-485 인프라를 그대로 유지하면서 현대 네트워크 시스템과 연동할 수 있다는 점이 이 게이트웨이의 핵심 가치입니다. 아래 시나리오에서 실질적인 도입 효과를 확인할 수 있습니다.

  • 산업 자동화 / SCADA 연동: Modbus RTU 기반 PLC·센서를 교체 없이 기존 SCADA 시스템의 Modbus TCP 인터페이스에 연결. 설비 투자 없이 디지털 전환 가능
  • 스마트 선박 / 항법 데이터 통합: 구형 NMEA 0183 선속계·수심계·GPS 수신기를 NMEA 2000 CAN 백본에 연결. 최신 차트 플로터(MFD)에서 레거시 센서 데이터 표시
  • 에너지 모니터링 인프라: 전력량계, 온도 센서 등 Modbus RTU 계측기 데이터를 UDP JSON 브로드캐스트로 수집 서버에 전달. 별도 드라이버 개발 없이 시각화 가능
  • 분산 원격 센서 노드: 복수의 ESP32-S3-Gateway를 현장 곳곳에 배치하고 중앙 Modbus TCP 클라이언트(SCADA 또는 Python 스크립트)에서 통합 폴링

한계 및 개선 방향

현재 한계

  • stale data 위험: 슬레이브 통신 단절 시 valid=false로 표시되나, 캐시의 마지막 값이 클라이언트에 계속 노출될 수 있음
  • 읽기 전용 Modbus TCP: FC03/FC04만 지원. FC05(코일 쓰기), FC06/FC16(레지스터 쓰기) 미구현 → 액추에이터 제어 용도로는 사용 불가
  • 단일 RS-485 포트: Modbus RTU와 NMEA 0183 모드를 동시에 운용 불가. 두 종류의 레거시 장비를 동시에 연결하려면 하드웨어 추가 필요
  • NMEA 2000 비인증: 상용 선박 시스템 공식 연동에는 인증 절차 필요
  • W5500 소켓 제한: 동시 TCP 클라이언트 최대 4개 → 대규모 다중 구독 환경에서는 병목 가능성

개선 방향

Modbus TCP 쓰기 기능 추가는 산업 제어 시스템 적용 범위를 크게 확장할 수 있는 현실적인 다음 단계입니다. FC06(단일 레지스터 쓰기)부터 순차적으로 구현하는 방식이 안전합니다.

이중 RS-485 포트 구성을 위해서는 ESP32-S3의 남은 UART(UART0 또는 UART2)와 추가 MAX485를 활용할 수 있습니다. Modbus RTU와 NMEA 0183을 동시에 수용하면 복합 장비 환경에서의 활용성이 크게 향상됩니다.

W5500 소켓 확장 측면에서는, 현재 4개로 제한된 동시 TCP 클라이언트를 W5500의 최대 8소켓까지 확장하거나, 더 많은 동시 연결이 필요한 환경이라면 **W6100(IPv6 지원, 멀티 소켓 강화)**으로 마이그레이션하는 경로도 검토할 수 있습니다.

데이터 유효성 관리 개선 차원에서 stale data 타임아웃 임계값을 설정하고, 일정 시간 이상 갱신이 없는 레지스터에 Modbus Exception(0x04, Slave Device Failure)을 반환하는 구조를 추가하면 클라이언트 측의 장애 감지가 명확해집니다.


FAQ

Q1. 하드웨어를 직접 조립해야 하나요? 난이도는 어느 정도인가요? ESP32-S3-DevKitM-1 보드, W5500 SPI 모듈, MAX485 트랜시버, ISO-1050 CAN 트랜시버를 GPIO 핀 연결 수준으로 조립합니다. 납땜이 가능한 중급 메이커라면 수 시간 내 완성할 수 있습니다. PlatformIO와 VS Code 환경에서 pio run --target upload 한 줄로 플래싱됩니다.

Q2. W5500 이더넷과 WiFi를 동시에 사용하면 IP 충돌이 생기지 않나요? 두 인터페이스는 서로 다른 IP 주소를 독립적으로 할당받아 운용됩니다. W5500은 DHCP 또는 정적 IP 설정이 가능하며, 게이트웨이 시작 로그에서 각 인터페이스의 IP를 별도로 확인할 수 있습니다.

Q3. Modbus TCP로 레지스터 쓰기(Write)도 가능한가요? 현재 버전은 FC03(Read Holding Registers)과 FC04(Read Input Registers) 읽기 기능만 지원합니다. 액추에이터 제어나 파라미터 설정이 필요한 경우, 소스 코드에 FC06/FC16을 추가 구현해야 합니다.

Q4. NMEA 2000 기능을 실제 선박에 적용해도 되나요? 프로젝트 README에서 공식 NMEA 2000 인증을 받지 않은 기기임을 명시하고 있습니다. 연구·프로토타입·개인 선박 용도로는 충분히 활용 가능하지만, 상용 선박의 안전 관련 시스템에는 인증된 장비 사용을 권장합니다.

Q5. Modbus RTU 슬레이브가 8개 이상이면 어떻게 되나요? 현재 펌웨어는 최대 8개의 슬레이브 ID를 폴링 목록에 등록할 수 있습니다. 8개 초과 시에는 소스 코드에서 상수값을 수정하거나, 여러 게이트웨이를 병렬 배치하는 방식으로 확장할 수 있습니다.



Summary

ESP32-S3-Gateway is an open-source firmware gateway that simultaneously converts RS-485 legacy instruments into three modern protocols: Modbus TCP, UDP, and NMEA 2000. The core design insight is a dual-network architecture — the W5500 SPI Ethernet module handles all industrial wired data traffic, while the ESP32-S3's built-in WiFi is reserved exclusively for web-based configuration and monitoring. With full runtime parameter editing via a browser UI, this project offers a practical, low-cost legacy integration solution for both industrial and marine environments.


Overview

RS-485 serial bus devices remain deeply embedded in industrial facilities and vessels worldwide. Modbus RTU sensors, meters, and NMEA 0183 navigation instruments carry decades of proven reliability — but they cannot participate directly in modern network infrastructure. The typical answer is expensive commercial gateways or full equipment replacement.

ESP32-S3-Gateway bridges this gap with an open-source approach. By combining an ESP32-S3, a W5500 Ethernet module, a CAN transceiver, and an RS-485 transceiver, it implements Modbus RTU → Modbus TCP/UDP conversion and NMEA 0183 → NMEA 2000 conversion in a single device. Input mode (Modbus RTU Master or NMEA 0183 Listener) and all output targets are fully configurable at runtime through the web UI — no reflashing required.


Architecture

The system consists of three layers: an RS-485 input layer, a register cache, and a multi-protocol output layer.

Data flow summary:

  • RS-485 devices are polled on a configurable interval (default: 1 second) to update the register cache
  • Cache data is served via W5500 Ethernet as a Modbus TCP server (port 502) and periodic UDP JSON broadcast (default: every 2 seconds)
  • The same cache generates NMEA 2000 PGNs and transmits them over the CAN backbone (default: every 1 second)
  • The WiFi interface operates entirely independently — dedicated to configuration and monitoring, with no data traffic

Supported Protocols

Input Protocols (mutually exclusive)

ModeProtocolRole
Mode 0Modbus RTU MasterPolls up to 8 slaves sequentially, up to 64 registers per slave
Mode 1NMEA 0183 ListenerParses Heading / Depth / Speed / Position sentences

Both modes share the same RS-485 GPIO pins and can be switched at runtime via the web UI.

Output Protocols (run simultaneously)

  • Modbus TCP Server: FC03 (Read Holding) / FC04 (Read Input), up to 4 simultaneous clients. Supports Unit ID routing or flat address space
  • UDP Broadcast: JSON format (ts, slaves[], id, valid, regs[]), configurable interval and port
  • NMEA 2000: Transmits four PGNs — 127250 (Heading), 128267 (Depth), 128259 (Speed Through Water), 129025 (Position Rapid Update)

Where W5500 Fits: Dual-Network Architecture

In this project, the W5500 is not simply an Ethernet add-on — it serves as the dedicated handler for all industrial data traffic.

Network role separation:

  • WiFi (ESP32-S3 internal): Management-only interface. Serves the web UI, REST API, and live register monitor. This is the access path for field engineers making configuration changes.
  • W5500 Ethernet: Data-only interface. Provides Modbus TCP server (port 502) and UDP broadcast under a separate IP address. This is the path for SCADA systems, PLCs, and data collection clients.

The two interfaces operate with independent IP addresses on physically separate networks. For example: WiFi at 192.168.1.55, W5500 Ethernet at 192.168.1.56.

W5500 hardwired TCP/IP offloading:

The firmware uses arduino-libraries/Ethernet, which drives the W5500's on-chip hardwired TCP/IP stack directly. The ESP32 controls W5500 socket registers over SPI; TCP connection management, packet processing, and reassembly are handled entirely inside the W5500. The result:

  • Reduced ESP32 load: TCP/IP processing is offloaded to the W5500, freeing the ESP32 to focus on protocol conversion logic and NMEA 2000 generation
  • Deterministic network response: Lower latency variance compared to software TCP/IP stacks
  • 4 simultaneous clients: Four of W5500's eight hardware sockets are allocated to Modbus TCP connections

Web UI and Runtime Configuration

📷 [Image needed: Web UI screenshot or configuration interface illustration] → Source image URL: Not available

One of the most practical aspects of this project is its fully runtime-configurable design.

  • First boot: Without stored WiFi credentials, the gateway starts a soft AP (ESP32-Gateway / config1234) — configuration starts immediately from a browser
  • Configurable parameters: RS-485 mode, slave ID list, register range, poll interval, TCP/UDP ports, NMEA 2000 register mappings, W5500 static IP — all editable from the web UI
  • Persistence: All settings are stored in ESP32 NVS (Non-Volatile Storage) and survive power cycles
  • REST API: /api/config (GET/POST), /api/regs (GET), /api/reset (POST) — enables automated configuration management from external systems
  • Live register monitor: Displays all register values by slave ID in real time, refreshed every 2 seconds at the bottom of the web UI

Technical Highlights

Cache-based multi-client architecture:

RS-485 polling results are held in a RAM register cache shared by all output consumers — Modbus TCP, UDP, and NMEA 2000. This decouples RS-485 polling from client response timing, delivering consistent response speed to multiple simultaneous clients.

Dual addressing schemes for Modbus TCP:

  • Unit ID routing: The client's Modbus Unit ID maps directly to the RS-485 slave ID, with register offset 0–63 within that slave's block
  • Flat address space: With Unit ID 0x00 or 0xFF, use (slave_id - 1) × 64 + register_index to address the entire slave space as a single flat range

Automatic NMEA 2000 PGN generation: Register cache values are scaled by configurable factors and mapped to four PGN types automatically. For example, a Heading register value of 1234× 0.1123.4° → transmitted as PGN 127250. PGN transmission halts automatically when the source slave's valid flag is false.


Business Value and Use Cases

The core value of this gateway is enabling legacy RS-485 infrastructure to connect with modern networked systems — without equipment replacement. Consider these practical scenarios:

  • Industrial automation / SCADA integration: Connect Modbus RTU PLCs and sensors to existing SCADA systems via Modbus TCP, without touching field wiring. A direct path to digitization without capital expenditure
  • Smart vessel / navigation data integration: Bridge legacy NMEA 0183 speed logs, depth sounders, and GPS receivers to a NMEA 2000 CAN backbone, making their data visible on modern chart plotters and MFDs
  • Energy monitoring infrastructure: Collect data from Modbus RTU power meters and temperature sensors via UDP JSON broadcast to a collection server — no custom driver development needed
  • Distributed remote sensor nodes: Deploy multiple ESP32-S3-Gateway units across a facility, with a central Modbus TCP client (SCADA system or Python script) polling all nodes from a single endpoint

Limitations and Future Improvements

Current Limitations

  • Stale data exposure: When a slave disconnects, the valid flag is set to false, but the last cached register values remain visible to Modbus TCP clients
  • Read-only Modbus TCP: Only FC03 and FC04 are supported. FC05 (single coil write), FC06, and FC16 (register writes) are not implemented — the gateway cannot control actuators
  • Single RS-485 port: Modbus RTU and NMEA 0183 modes cannot run simultaneously. Connecting both types of legacy devices requires additional hardware
  • NMEA 2000 non-certified: The README explicitly notes this device has not passed NMEA 2000 certification — not suitable for safety-critical systems on commercial vessels
  • W5500 socket ceiling: Maximum 4 simultaneous TCP clients — a potential bottleneck in large multi-subscriber environments

Future Improvements

Adding Modbus TCP write support is the most impactful next step for industrial control applications. Implementing FC06 (single register write) first is a safe incremental path.

A dual RS-485 port configuration is achievable using ESP32-S3's additional UART peripherals (UART0 or UART2) with a second MAX485 transceiver. Running Modbus RTU and NMEA 0183 simultaneously would significantly broaden applicability in mixed-device environments.

For environments requiring more than 4 simultaneous TCP connections, upgrading to W6100 (which offers enhanced multi-socket support and IPv6 compatibility) is a natural migration path within the WIZnet product lineup.

On data validity management, adding a configurable stale-data timeout — where registers not updated within a threshold period return a Modbus Exception (0x04, Slave Device Failure) instead of cached values — would give client systems a clear and reliable failure signal.


FAQ

Q1. How difficult is the hardware assembly? Do I need advanced skills? Assembly involves GPIO-level wiring between the ESP32-S3-DevKitM-1, W5500 SPI module, MAX485 transceiver, and ISO-1050 CAN transceiver. An intermediate maker comfortable with soldering can complete the build in a few hours. Flashing is a single command: pio run --target upload via PlatformIO in VS Code.

Q2. Will the W5500 Ethernet and WiFi IP addresses conflict with each other? No. The two interfaces receive independent IP addresses and operate on separate network paths. W5500 supports both DHCP and static IP assignment. Both assigned IPs are printed to the serial monitor at startup.

Q3. Can I write Modbus registers through the TCP interface? The current firmware supports FC03 and FC04 (read-only). Write function codes (FC05, FC06, FC16) are not yet implemented. If actuator control or remote parameter setting is required, these function codes must be added to the source code.

Q4. Is the NMEA 2000 output safe to use on a real vessel? The project README explicitly states this is not a certified NMEA 2000 device. It is well-suited for research, prototyping, and personal vessel use. For safety-critical systems on commercial vessels, certified equipment is strongly recommended.

Q5. What happens if I need more than 8 Modbus RTU slaves? The current firmware supports a polling list of up to 8 slave IDs. Beyond that limit, either modify the constant in the source code or deploy multiple gateway units in parallel, each covering a separate slave ID range.


Documents
Comments Write