Wiznet makers

Lihan__

Published May 31, 2026 ©

67 UCC

8 WCC

3 VAR

0 Contests

0 Followers

0 Following

Original Link

esp32-modbus-mqtt-bridge

ESP32-S3 Modbus-MQTT Bridge — KinCony RS485 relay controller to Home Assistant via MQTT. Dual-network, Digest Auth, auto-provisioning, OTA updates.

COMPONENTS
PROJECT DESCRIPTION

ESP32-S3 Modbus-MQTT Bridge — Giving Industrial RS485 Relays a Home in Home Assistant

#W5500 #ESP32S3 #TCP_TOE #Modbus #MQTT #HomeAssistant #RS485 #KinCony #DualNetwork #OTA

📚 Context: Smart-home / light-industrial automation — a polished, MIT-licensed firmware by Zsolt Lakatos that bridges KinCony industrial Modbus relay controllers to Home Assistant. 🔧 Verification status: Public repo, 18 commits, tagged release v2.2.0 (May 28, 2026), PlatformIO build with separate dev/prod environments, clang-format + cppcheck configs, and a test/ directory — a maintained, build-reproducible project. The README documents an explicit W5500 + ESP32-S3 (Waveshare) pin map and full network-failover behavior.


01 — What is this project?

KinCony controllers (the F16, A16, KC868 family) are popular, affordable industrial relay boards — but they speak Modbus RTU over RS485, a wired serial protocol that Home Assistant doesn't natively consume in a plug-and-play way. Getting 16 or 32 relays plus digital inputs into HA usually means hand-writing YAML, fighting register maps, and babysitting a fragile serial link.

This project is the missing translator. It's firmware for an ESP32-S3 that:

  1. Talks Modbus RTU down one side (RS485 → KinCony relays/DIs),
  2. Speaks MQTT with Home Assistant Auto-Discovery up the other side — so every relay becomes a switch entity and every digital input a binary_sensor, appearing in HA automatically with zero manual config,
  3. And — crucially — does its networking over a W5500 wired-Ethernet primary link with Wi-Fi failover, so the bridge between an industrial bus and a home automation system never silently drops off the network.

The whole thing is configured through a dark-themed 6-tab web dashboard, supports OTA firmware updates, JSON backup/restore, and Digest-authenticated write endpoints.

02 — Why a wired bridge for Modbus → MQTT?

🔷 Industrial control deserves an industrial-grade link

Relay control is the kind of thing where "the Wi-Fi dropped" is not an acceptable failure mode — you don't want lights, pumps, or HVAC contactors stuck because of RF congestion. A wired W5500 Ethernet link as primary gives the bridge deterministic connectivity, with Wi-Fi STA as automatic fallback and a Wi-Fi AP always broadcasting for emergency access.

🔷 MQTT Auto-Discovery removes the worst part of HA integration

Instead of hand-authoring HA configuration, the firmware publishes MQTT discovery messages (modbusmqtt/KinCony_F16/relay/1/config) so entities self-register under HA's Devices page. The bridge turns a register-level industrial protocol into first-class HA entities.

🔷 WIZnet ecosystem fit

The ESP32-S3, unlike the original ESP32, has no internal Ethernet MAC. To give it reliable wired networking you need an external MAC+PHY — and the W5500, with its full hardware TCP/IP stack and 8 hardware sockets, is the standard choice (as reflected by the Waveshare W5500 + ESP32-S3 reference pinout this project targets). It lets the MCU spend its cycles on Modbus polling and the web UI rather than on a software TCP stack.

03 — System architecture

   ┌──────────────┐   RS485 (Modbus RTU)   ┌────────────────────┐
   │  KinCony F16 │◄──────────────────────►│     ESP32-S3       │
   │ 16 relays +  │   GPIO44 RX / 43 TX    │                    │
   │   6 DI       │   GPIO4 DE (direction) │  ┌──────────────┐  │
   │  addr 200    │                        │  │   W5500 LAN  │  │
   └──────────────┘                        │  │ (HW TCP/IP)  │  │
                                            │  │ SPI: MOSI11  │  │
                                            │  │ MISO9 SCLK13 │◄─┼─ RJ45 ─ LAN (primary ✅)
                                            │  │ CS12 INT14   │  │
                                            │  │ RST21        │  │
                                            │  └──────┬───────┘  │
                                            │         │          │
                                            │   Web UI :80 (TCP)  │
                                            │   MQTT client (TCP) │
                                            └─────────┬──────────┘
                                                      │
                          ┌───────────────────────────┼───────────────┐
                          │                           │               │
                     LAN (W5500)               WiFi STA          WiFi AP
                     Primary ✅                Fallback         Always-on
                          │                                     192.168.4.1
                          ▼
                   MQTT Broker  192.168.1.43:1883
                          │
                  ┌───────┴────────┐
                  │ Home Assistant  │
                  │ Auto-Discovery  │
                  └────────────────┘

04 — Why W5500? ⭐

🔷 Always-on link for an always-on bridge

A Modbus-to-MQTT bridge is only useful if it's continuously reachable — by the broker, by the web UI, by OTA updates. The W5500's hardware TCP/IP stack maintains the MQTT TCP connection and the HTTP server socket in silicon, so the ESP32-S3 can keep tight RS485 polling timing without the jitter a software network stack would introduce.

🔷 Usage mode: TCP (TOE) — MQTT client + HTTP server

This project uses the W5500 purely in TCP (TOE) socket mode. Two TCP roles run over the chip:

  • An outbound MQTT client connection to the broker (192.168.1.43:1883) carrying HA auto-discovery and relay state.
  • An inbound HTTP server (port 80) serving the 6-tab dashboard, the REST-ish API (/api/status, /relay, /ota, etc.), and OTA firmware upload.

Both are stream-oriented, connection-based — the textbook case for the W5500's hardware TCP offload. (No UDP/multicast discovery path is used here; HA discovery rides over the MQTT TCP session, not mDNS.)

Note on integration: the firmware targets the Waveshare W5500 + ESP32-S3 reference pinout and is built with PlatformIO. As with most ESP32-S3 + W5500 designs, the chip is driven as an SPI-attached Ethernet interface beneath the ESP-IDF / Arduino-ESP32 networking stack rather than through WIZnet's native ioLibrary socket API. The physical networking is unambiguously W5500; the exact driver layer (ESP-IDF ETH vs. an Ethernet-over-SPI library) is inferred from the pin map and dual-network architecture rather than confirmed from the src/ files, which were not directly readable.

🔷 Why W5500 over the alternatives here

  • vs. Wi-Fi-only: unacceptable for relay control; W5500 provides the deterministic wired primary, Wi-Fi is fallback only.
  • vs. ESP32-S3 internal Ethernet: there is none — the S3 has no internal EMAC, so an external SPI MAC+PHY is required.
  • vs. ENC28J60 / bare PHY + software stack: the W5500's hardware TCP/IP and 8 sockets keep network handling off the MCU, leaving headroom for Modbus polling, the web server, and MQTT simultaneously.

🔷 Verified evidence ✅

  • README lists W5500 explicitly as the primary network with automatic failover.
  • Full Waveshare W5500 + ESP32-S3 pin map (MOSI 11, MISO 9, SCLK 13, CS 12, INT 14, RST 21).
  • Network architecture diagram showing LAN(W5500) primary → WiFi STA fallback → WiFi AP always-on, with automatic failback.
  • MQTT broker target, HA auto-discovery topic format, and HTTP/OTA endpoints all documented — confirming the TCP roles the chip carries.
  • Tagged release v2.2.0 and PlatformIO prod build (firmware.bin, ~1MB) indicate a real, flashable artifact.

05 — Key components

🌐 WIZnet W5500 — TCP (TOE), SPI-attached, primary network

The wired networking backbone. Carries the MQTT client connection and the HTTP/OTA server, and is the always-primary interface with Wi-Fi failover beneath it.

📟 ESP32-S3

The bridge MCU — runs Modbus master polling on RS485 and the dual-network stack. Chosen partly because it needs an external Ethernet controller (no internal MAC), making the W5500 a natural pairing.

🔌 RS485 transceiver

Connects the ESP32-S3 UART (RX GPIO44 / TX GPIO43, DE GPIO4) to the KinCony Modbus bus.

🏭 KinCony F16 / A16 controllers

The industrial relay+DI endpoints (F16 = 16 relays + 6 DI at address 200; A16 = 32 relays), or any generic Modbus RTU device via a configurable register map.

🏠 Home Assistant + MQTT broker

The consumer of the bridge's output — relays and DIs appear automatically as switch and binary_sensor entities via MQTT auto-discovery.

06 — Application scenarios

01. Whole-home relay automation — Bring a KinCony F16/A16 board's 16–32 relays and digital inputs into Home Assistant as native entities, controlling lighting, pumps, gates, or HVAC contactors.

02. Retrofitting legacy Modbus equipment — Any generic Modbus RTU device with a known register map can be exposed to HA through the configurable profile, modernizing older industrial gear without ripping it out.

03. Light-industrial / workshop control — Reliable wired-primary networking makes this suitable for workshop or small-facility relay control where Wi-Fi alone would be risky.

04. Fleet of bridges with OTA — Web-based OTA and JSON backup/restore make it practical to deploy and maintain multiple bridge units across a building.

Conclusion

This project turns an industrial RS485 Modbus relay controller into a set of plug-and-play Home Assistant entities — and leans on the W5500 to keep that bridge on a deterministic wired link, because relay control is exactly the place you can't afford a flaky network.

  • ✅ Real, maintained firmware (MIT, v2.2.0, PlatformIO, dev/prod builds, lint + test configs)
  • ✅ W5500 used as the primary wired network with automatic Wi-Fi failover/failback
  • ✅ W5500 in TCP (TOE) mode carrying both an MQTT client and an HTTP/OTA server
  • ✅ MQTT Auto-Discovery — relays/DIs self-register in Home Assistant, no manual YAML
  • ✅ Web dashboard (6 tabs), Digest Auth on write endpoints, OTA, JSON backup/restore
  • ✅ Auto-provisioning on first boot — flash, power on, configure via browser
  • ✅ Explicit Waveshare W5500 + ESP32-S3 pin map documented and reproducible

Q&A

Q. Which W5500 socket mode does this use? A. TCP (TOE) only. The chip carries an outbound MQTT client connection and an inbound HTTP server (port 80) for the web UI and OTA — both stream-based TCP. There's no UDP/mDNS path; HA discovery rides the MQTT TCP session.

Q. Why is the W5500 the primary network and not Wi-Fi? A. Relay control needs deterministic connectivity. Wired Ethernet via the W5500 is immune to the RF congestion that can stall Wi-Fi, so it's primary; Wi-Fi STA is only a fallback, and a Wi-Fi AP stays up for emergency access.

Q. Could the ESP32-S3 just use built-in Ethernet instead? A. No — the ESP32-S3 has no internal Ethernet MAC. An external SPI controller like the W5500 is the standard and necessary way to give it wired networking.

Q. Is the W5500 driven through WIZnet's ioLibrary? A. Most likely no — this targets the Waveshare ESP32-S3 + W5500 reference design and is built with PlatformIO, which typically drives the W5500 as an SPI Ethernet interface under the ESP-IDF/Arduino stack. This is inferred from the pin map and architecture; the src/ source files weren't directly readable to confirm the exact driver layer.


ESP32-S3 Modbus-MQTT 브리지 — 산업용 RS485 릴레이에게 Home Assistant 안의 집을 마련해주다

#W5500 #ESP32S3 #TCP_TOE #Modbus #MQTT #HomeAssistant #RS485 #KinCony #DualNetwork #OTA

📚 컨텍스트: 스마트홈 / 경산업 자동화 — Zsolt Lakatos가 만든 잘 다듬어진 MIT 라이선스 펌웨어로, KinCony 산업용 Modbus 릴레이 컨트롤러를 Home Assistant에 연결한다. 🔧 검증 상태: 공개 저장소, 18 커밋, 태그 릴리스 v2.2.0 (2026년 5월 28일), dev/prod 환경을 분리한 PlatformIO 빌드, clang-format + cppcheck 설정, test/ 디렉터리 — 유지보수되고 빌드 재현 가능한 프로젝트. README는 명시적인 W5500 + ESP32-S3(Waveshare) 핀 맵과 전체 네트워크 페일오버 동작을 문서화하고 있다.


01 — 이 프로젝트는 무엇인가?

KinCony 컨트롤러(F16, A16, KC868 계열)는 인기 있고 저렴한 산업용 릴레이 보드다 — 하지만 이들은 유선 시리얼 프로토콜인 RS485 기반 Modbus RTU로 통신하며, Home Assistant는 이를 플러그앤플레이 방식으로 기본 지원하지 않는다. 16개 또는 32개의 릴레이와 디지털 입력을 HA에 넣으려면 보통 YAML을 손으로 작성하고, 레지스터 맵과 씨름하며, 취약한 시리얼 링크를 돌봐야 한다.

이 프로젝트는  번역기다. ESP32-S3용 펌웨어로서:

  1. 한쪽으로는 Modbus RTU를 말하고(RS485 → KinCony 릴레이/DI),
  2. 다른 쪽으로는 Home Assistant 자동 발견(Auto-Discovery)을 갖춘 MQTT를 말한다 — 모든 릴레이는 switch 엔티티로, 모든 디지털 입력은 binary_sensor로 변환되어, 수동 설정 없이 HA에 자동으로 나타난다,
  3. 그리고 결정적으로, 네트워킹을 W5500 유선 이더넷 주 링크 + Wi-Fi 페일오버로 처리한다 — 산업용 버스와 홈 오토메이션 시스템 사이의 다리가 네트워크에서 조용히 떨어지는 일이 없도록.

전체는 다크 테마 6탭 웹 대시보드로 설정하며, OTA 펌웨어 업데이트, JSON 백업/복원, Digest 인증 쓰기 엔드포인트를 지원한다.

02 — 왜 Modbus → MQTT를 유선 브리지로?

🔷 산업 제어에는 산업급 링크가 필요하다

릴레이 제어는 "Wi-Fi가 끊겼어요"가 용납되는 실패 모드가 아니다 — RF 혼잡 때문에 조명, 펌프, HVAC 접촉기가 멈춰서는 안 된다. W5500 유선 이더넷을 주 링크로 두면 브리지에 결정론적 연결성을 주고, Wi-Fi STA는 자동 폴백으로, Wi-Fi AP는 비상 접근용으로 항상 송출된다.

🔷 MQTT 자동 발견이 HA 통합의 가장 괴로운 부분을 없앤다

HA 설정을 손으로 작성하는 대신, 펌웨어가 MQTT 발견 메시지(modbusmqtt/KinCony_F16/relay/1/config)를 발행해 엔티티가 HA의 장치 페이지에 스스로 등록된다. 브리지는 레지스터 수준의 산업 프로토콜을 일급 HA 엔티티로 바꿔준다.

🔷 WIZnet 생태계 적합성

ESP32-S3는 오리지널 ESP32와 달리 내장 이더넷 MAC이 없다. 신뢰할 수 있는 유선 네트워킹을 주려면 외부 MAC+PHY가 필요한데, 완전한 하드웨어 TCP/IP 스택과 8개 하드웨어 소켓을 갖춘 W5500이 표준 선택이다(이 프로젝트가 타깃하는 Waveshare W5500 + ESP32-S3 레퍼런스 핀아웃이 이를 반영). 덕분에 MCU는 소프트웨어 TCP 스택이 아니라 Modbus 폴링과 웹 UI에 사이클을 쓸 수 있다.

03 — 시스템 아키텍처

04 — 왜 W5500인가? ⭐

🔷 항상 켜진 브리지를 위한 항상 켜진 링크

Modbus-to-MQTT 브리지는 브로커, 웹 UI, OTA 업데이트로부터 계속 도달 가능할 때만 유용하다. W5500의 하드웨어 TCP/IP 스택은 MQTT TCP 연결과 HTTP 서버 소켓을 실리콘에서 유지하므로, ESP32-S3는 소프트웨어 네트워크 스택이 유발할 지터 없이 빠듯한 RS485 폴링 타이밍을 유지할 수 있다.

🔷 사용 모드: TCP (TOE) — MQTT 클라이언트 + HTTP 서버

이 프로젝트는 W5500을 순수하게 TCP(TOE) 소켓 모드로 사용한다. 칩 위에서 두 가지 TCP 역할이 돈다.

  • 브로커(192.168.1.43:1883)로의 아웃바운드 MQTT 클라이언트 연결 — HA 자동 발견과 릴레이 상태를 운반.
  • 인바운드 HTTP 서버(포트 80) — 6탭 대시보드, REST 유사 API(/api/status, /relay, /ota 등), OTA 펌웨어 업로드 제공.

둘 다 스트림 지향·연결 기반으로, W5500의 하드웨어 TCP 오프로드에 딱 맞는 교과서적 사례다. (여기서는 UDP/멀티캐스트 발견 경로를 쓰지 않는다 — HA 발견은 mDNS가 아니라 MQTT TCP 세션 위에서 이뤄진다.)

통합 방식에 대한 참고: 펌웨어는 Waveshare W5500 + ESP32-S3 레퍼런스 핀아웃을 타깃하며 PlatformIO로 빌드된다. 대부분의 ESP32-S3 + W5500 설계처럼, 칩은 WIZnet 네이티브 ioLibrary 소켓 API가 아니라 ESP-IDF / Arduino-ESP32 네트워킹 스택 아래의 SPI 연결 이더넷 인터페이스로 구동된다. 물리적 네트워킹이 W5500인 것은 명백하지만, 정확한 드라이버 레이어(ESP-IDF ETH 대 Ethernet-over-SPI 라이브러리)는 src/ 파일을 직접 읽지 못해 핀 맵과 듀얼 네트워크 구조에서 추론한 것이다.

🔷 대안 대비 W5500의 우위

  • vs. Wi-Fi 단독: 릴레이 제어에 부적합 — W5500이 결정론적 유선 주 경로를 제공하고 Wi-Fi는 폴백 전용.
  • vs. ESP32-S3 내장 이더넷: 존재하지 않음 — S3에는 내장 EMAC이 없어 외부 SPI MAC+PHY가 필수.
  • vs. ENC28J60 / 베어 PHY + 소프트웨어 스택: W5500의 하드웨어 TCP/IP와 8개 소켓이 네트워크 처리를 MCU에서 덜어내, Modbus 폴링·웹 서버·MQTT를 동시에 돌릴 여유를 남긴다.

🔷 검증된 증거 ✅

  • README가 W5500을 자동 페일오버를 갖춘 주 네트워크로 명시.
  • 완전한 Waveshare W5500 + ESP32-S3 핀 맵(MOSI 11, MISO 9, SCLK 13, CS 12, INT 14, RST 21).
  • LAN(W5500) 주 → WiFi STA 폴백 → WiFi AP 상시의 네트워크 아키텍처 다이어그램과 자동 페일백.
  • MQTT 브로커 타깃, HA 자동 발견 토픽 형식, HTTP/OTA 엔드포인트 모두 문서화 — 칩이 운반하는 TCP 역할 확인.
  • 태그 릴리스 v2.2.0과 PlatformIO prod 빌드(firmware.bin, ~1MB)가 실제 플래시 가능한 산출물임을 시사.

05 — 핵심 구성 요소

🌐 WIZnet W5500 — TCP(TOE), SPI 연결, 주 네트워크

유선 네트워킹의 중추. MQTT 클라이언트 연결과 HTTP/OTA 서버를 운반하며, Wi-Fi 페일오버를 그 아래에 둔 상시 주 인터페이스다.

📟 ESP32-S3

브리지 MCU — RS485에서 Modbus 마스터 폴링과 듀얼 네트워크 스택을 구동한다. 외부 이더넷 컨트롤러가 필요해(내장 MAC 없음) W5500과 자연스럽게 짝지어진다.

🔌 RS485 트랜시버

ESP32-S3 UART(RX GPIO44 / TX GPIO43, DE GPIO4)를 KinCony Modbus 버스에 연결.

🏭 KinCony F16 / A16 컨트롤러

산업용 릴레이+DI 엔드포인트(F16 = 릴레이 16개 + DI 6개, 주소 200; A16 = 릴레이 32개), 또는 설정 가능한 레지스터 맵을 통한 임의의 Modbus RTU 장치.

🏠 Home Assistant + MQTT 브로커

브리지 출력의 소비자 — 릴레이와 DI가 MQTT 자동 발견을 통해 switch/binary_sensor 엔티티로 자동 등장.

06 — 응용 시나리오

01. 전체 주택 릴레이 자동화 — KinCony F16/A16 보드의 16~32개 릴레이와 디지털 입력을 HA 네이티브 엔티티로 가져와 조명, 펌프, 게이트, HVAC 접촉기를 제어.

02. 레거시 Modbus 장비 리트로핏 — 알려진 레지스터 맵을 가진 임의의 Modbus RTU 장치를 설정 가능한 프로파일로 HA에 노출 — 오래된 산업 장비를 교체 없이 현대화.

03. 경산업 / 작업장 제어 — 신뢰할 수 있는 유선 주 네트워킹 덕분에 Wi-Fi 단독이 위험할 작업장·소규모 시설 릴레이 제어에 적합.

04. OTA를 갖춘 브리지 플릿 — 웹 기반 OTA와 JSON 백업/복원으로 건물 전반에 여러 브리지 유닛을 배포·유지보수하기 용이.

결론

이 프로젝트는 산업용 RS485 Modbus 릴레이 컨트롤러를 플러그앤플레이 Home Assistant 엔티티 묶음으로 바꾼다 — 그리고 W5500에 기대어 그 다리를 결정론적 유선 링크 위에 유지한다. 릴레이 제어야말로 불안정한 네트워크를 감당할 수 없는 영역이기 때문이다.

  • ✅ 실제로 유지보수되는 펌웨어 (MIT, v2.2.0, PlatformIO, dev/prod 빌드, 린트 + 테스트 설정)
  • ✅ W5500을 자동 Wi-Fi 페일오버/페일백을 갖춘 주 유선 네트워크로 사용
  • ✅ W5500을 TCP(TOE) 모드로 사용 — MQTT 클라이언트와 HTTP/OTA 서버를 함께 운반
  • ✅ MQTT 자동 발견 — 릴레이/DI가 HA에 스스로 등록, 수동 YAML 불필요
  • ✅ 웹 대시보드(6탭), 쓰기 엔드포인트 Digest 인증, OTA, JSON 백업/복원
  • ✅ 첫 부팅 자동 프로비저닝 — 플래시하고 전원만 켜면 브라우저로 설정
  • ✅ 명시적이고 재현 가능한 Waveshare W5500 + ESP32-S3 핀 맵 문서화

Q&A

Q. W5500의 어떤 소켓 모드를 사용하나? A. TCP(TOE)만. 칩은 아웃바운드 MQTT 클라이언트 연결과 웹 UI·OTA용 인바운드 HTTP 서버(포트 80)를 운반한다 — 둘 다 스트림 기반 TCP. UDP/mDNS 경로는 없으며, HA 발견은 MQTT TCP 세션 위에서 이뤄진다.

Q. 왜 Wi-Fi가 아니라 W5500이 네트워크인가? A. 릴레이 제어에는 결정론적 연결성이 필요하다. W5500 유선 이더넷은 Wi-Fi를 멈출 수 있는 RF 혼잡에 면역이라 주 경로이고, Wi-Fi STA는 폴백, Wi-Fi AP는 비상 접근용으로만 유지된다.

Q. ESP32-S3 내장 이더넷을 쓰면 안 되나? A. 안 된다 — ESP32-S3에는 내장 이더넷 MAC이 없다. W5500 같은 외부 SPI 컨트롤러가 유선 네트워킹을 부여하는 표준적이고 필수적인 방법이다.

Q. W5500을 WIZnet ioLibrary로 구동하나? A. 아마 아닐 것이다 — 이 프로젝트는 Waveshare ESP32-S3 + W5500 레퍼런스 설계를 타깃하고 PlatformIO로 빌드되며, 보통 W5500을 ESP-IDF/Arduino 스택 아래 SPI 이더넷 인터페이스로 구동한다. 이는 핀 맵과 아키텍처에서 추론한 것이며, 정확한 드라이버 레이어는 src/ 소스를 직접 읽지 못해 확정하지 못했다.

Documents
Comments Write