Wiznet makers

scott

Published July 03, 2026 ©

135 UCC

20 WCC

47 VAR

0 Contests

0 Followers

0 Following

Original Link

esp_thuydien

Never Lose a Reading: An ESP32-S3 + W5500 Remote Monitoring System for a Vietnamese Hydropower Station

COMPONENTS Hardware components

WIZnet - W5500

x 1


PROJECT DESCRIPTION

개요

수력발전소는 저수지 수위, 유입·방류량, 강우량, 발전량 등 다양한 물리량을 24시간 끊김 없이 계측해야 합니다. 문제는 현장 대부분이 유선 인터넷이 불안정하거나 부재한 산간·오지라는 점입니다. WiFi나 셀룰러가 잠깐씩 끊기는 건 일상이고, 그때마다 데이터가 사라지면 방재·발전 계획 양쪽에 구멍이 생깁니다.

esp_thuydien은 이 문제를 정면으로 다룹니다. ESP32-S3 한 대에 아날로그(4–20mA/0–10V), 엔코더, 디지털입력(우량계), RS485 Modbus RTU, Modbus TCP까지 붙이고, 통신이 끊기면 SD카드에 JSON으로 쌓아뒀다가 복구되는 즉시 순서대로 밀어 넣는 구조입니다. 60초 주기 실시간 전송(MQTT Publish)과 오프라인 백필 전송이 뮤텍스로 충돌 없이 공존하도록 설계된 점이 특히 눈에 띕니다.

왜 지금 이 시스템이 필요한가 — 베트남 수력댐 감시 의무화

이런 시스템이 "있으면 좋은 것"이 아니라 법적 의무에 가깝다는 점이 베트남 시장의 특징입니다.

  • 베트남 산업무역부(Bộ Công Thương)의 Thông tư 09/2019/TT-BCT는 수력댐·저수지 소유자에게 방류 운영에 대한 자동/온라인 감시 카메라·계측 장비 설치와, 재해대응위원회·성 인민위원회·수문기상총국·수자원관리국·전력조정국으로의 데이터 전송 의무를 명시합니다.
  • Thông tư 17/2021/TT-BTNMT는 저수지 수위 데이터를 국가 수문 데이터베이스로 실시간 전송하도록 규정합니다.
  • 2026년 4월, 산업무역부는 이 규정을 더 강화하는 신규 개정안을 공람 중입니다 (원격 감시·데이터베이스 동기화 요건 강화 방향).

실사례Sông Ba Hạ 수력발전소가 있습니다. 이 발전소는 저수지 수위·유입량·방류량·강우량 센서와 감시 카메라를 PLC로 연동해, 고정 IP를 통해 국가 수문 데이터 시스템에 자동 전송하는 디지털 전환을 완료했다고 언론(Tạp chí Công Thương, ERAV)에 보도되었습니다. 다만 이 사례는 상용 PLC+SCADA 솔루션 기반이며, esp_thuydien처럼 ESP32/WIZnet 임베디드 오픈소스 스택을 사용했는지는 확인 불가입니다.

즉, esp_thuydien 자체가 언론에 보도된 채택 사례는 아니지만, 이 프로젝트가 다루는 문제(다채널 계측 + 오프라인 백필 + 상향 전송)는 베트남 수력발전 산업 전반의 실제 규제 니즈와 정확히 겹칩니다.

→ 참고: Sông Ba Hạ 디지털 전환 보도

아키텍처

시스템은 4개의 FreeRTOS 태스크가 우선순위와 동기화 프리미티브로 명확히 역할을 분담합니다.

기술 배경

하드웨어 TCP/IP 오프로딩 (W5500)

W5500은 TCP/IP 스택 전체를 칩 내부 하드웨어로 처리하는 TOE(TCP Offload Engine) 기반 이더넷 컨트롤러입니다. MCU는 SPI로 소켓 레지스터만 주고받으면 되고, 패킷 처리·재전송·체크섬 계산은 칩이 전담합니다. esp_thuydien에서는 이 특성 덕분에 Modbus TCP 폴링이 WiFi 스택 부하와 완전히 분리되어, 무선 상태가 불안정해도 산업 계측 채널의 신뢰성이 흔들리지 않습니다.

Modbus RTU vs Modbus TCP

Modbus RTU는 RS485 직렬선을 통해 바이너리 프레임을 주고받는 방식으로, 배선이 단순하고 노이즈에 강해 산업 현장에서 널리 쓰입니다. Modbus TCP는 동일한 데이터 모델을 이더넷/IP 위에 얹은 것으로, 배선 거리 제약이 적고 여러 슬레이브를 네트워크로 묶을 수 있습니다. 이 프로젝트는 두 방식을 동시에 폴링해, 근거리 RS485 계측기와 원거리 IP 계측기를 하나의 게이트웨이로 통합합니다.

MQTT + 오프라인 백필 패턴

MQTT는 QoS 레벨로 전송 신뢰성을 보장하지만, 디바이스 자체가 오프라인이면 QoS도 소용없습니다. 이 프로젝트는 그 공백을 SD카드 로컬 저장으로 메웁니다. 온라인 상태에서는 실시간 전송(ingest_type: realtime), 오프라인 동안 쌓인 데이터는 복구 후 ingest_type: backfill로 구분해 전송합니다. 서버는 타임스탬프 지연(delay)을 계산해 5분 초과 시 is_late로 표시하도록 설계되어 있어, 백필 데이터와 실시간 데이터를 혼동하지 않습니다.

기술 특징

  • Worst-case 타이밍을 상수로 못 박은 설계: RTU 5슬레이브 타임아웃(5초) + TCP 5호스트 타임아웃(25초)을 더한 30,000msMODBUS_POLL_TIMEOUT_MS로 고정해뒀습니다. 타임아웃이 나도 해당 채널만 null로 처리하고 60초 발행 주기 자체는 절대 밀리지 않습니다.
  • EventGroup + Mutex로 실시간성 확보: modbusTask는 loop()보다 높은 우선순위(3)로 동작하며, s_mbEvent로 폴링 타이밍을, s_pubMutex로 실시간·백필 발행 충돌을 막습니다.
  • OTA는 32KB 별도 스택: mbedTLS ECDHE 핸드셰이크가 28KB 이상을 요구한다는 점을 인지하고 OTA 태스크만 별도 스택 크기로 분리했습니다 — 흔히 놓치는 디테일을 짚었다는 점에서 실전 경험이 묻어납니다.

Where WIZnet Fits

실제 사용된 모델: W5500

  • SPI 인터페이스(MOSI/MISO/CLK/CS = GPIO 36/38/37/39)로 연결
  • Modbus TCP 전용 채널(20채널, 5 slave×4 변수) 폴링을 전담
  • 같은 host:port로 묶이는 채널은 TCP 커넥션 1개로 합쳐서 폴링 시간을 절감하는 최적화 로직 포함

WiFi는 MQTT 업링크와 현장 웹 설정용으로, W5500은 산업용 Modbus TCP 슬레이브 폴링으로 역할이 명확히 분리되어 있습니다. 무선 네트워크가 불안정해도 계측 채널 자체의 신뢰성은 유지되는 구조입니다.

WIZnet Makers 유사 사례

  • esp32s3-modbus-gateway-gemini — ESP32-S3 + W5100S로 RS485/Modbus RTU·TCP·WiFi 3중 경로를 동시에 처리하는 범용 산업 게이트웨이 펌웨어입니다. esp_thuydien이 "센서 종단(edge)"이라면, 이쪽은 "프로토콜 변환 게이트웨이"로 지향점이 다릅니다. 

→ 프로젝트 링크: https://maker.wiznet.io/matthew/projects/esp32s3-modbus-gateway-gemini/

  • esp32-modbus-mqtt-bridge — ESP32-S3 + W5500을 유선 우선, WiFi 페일오버로 구성해 KinCony 산업용 릴레이를 Home Assistant에 연동합니다. "유선을 기본, 무선을 백업"으로 삼는 네트워킹 철학이 esp_thuydien과 동일합니다. 

→ 프로젝트 링크: https://maker.wiznet.io/Lihan__/projects/esp32-modbus-mqtt-bridge/

  • CanhbaongapLongAn — 베트남 롱안(Long An) 지역 홍수·염분 감시 스테이션으로, W5500 + RS485 Modbus RTU 조합과 "베트남 오지 인프라 원격계측"이라는 배경 서사가 동일합니다 (동일 저자 scott). 

→ 프로젝트 링크: https://maker.wiznet.io/scott/projects/canhbaongaplongan/

세 사례 모두 **"WiFi 단독으로는 산업 계측의 신뢰성을 담보할 수 없다"**는 동일한 결론에서 W5500(또는 W5100S)을 유선 백본으로 채택했다는 공통점이 있습니다.

항목본 프로젝트(esp_thuydien)esp32s3-modbus-gateway-geminiesp32-modbus-mqtt-bridgeCanhbaongapLongAn
MCUESP32-S3-WROOM-1-N16ESP32-S3ESP32-S3(Waveshare)ESP32(모델 미상)
WIZnet 칩W5500W5100SW5500W5500
네트워크 구조WiFi(MQTT)+W5500(TCP) 역할 분리WiFi+W5100S 다중 경로W5500 유선 우선+WiFi 페일오버W5500+RS485 중심
대상 분야수력발전 현장 계측범용 산업 게이트웨이스마트홈(Home Assistant)공공 인프라(홍수·염분)
오프라인 저장SD 백필(JSON, 자동 재전송)미상JSON 백업/복원미상
OTAHTTPS+SHA256 검증지원(세부 미상)지원미상

표에서 드러나듯, 네 프로젝트 모두 "유선 이더넷을 1차 네트워크로, WiFi를 보조로" 두는 설계 철학을 공유합니다. 다만 esp_thuydien만이 SD카드 백필을 명시적 FreeRTOS 태스크로 분리해 오프라인 복구 시나리오까지 구조화했다는 점이 차별점입니다.

비즈니스 가치

  • 수력발전소 저수지 감시: 원 프로젝트의 1차 용도. 규제 대응(Thông tư 09/2019/TT-BCT)과 직결
  • 정수장/양수장 원격계측: 유량계·수위계를 RS485/TCP로 묶고 SD 백필로 무인 운영소 데이터 무손실 확보
  • 관개수로 유량 관리: 엔코더 기반 유량 측정 + 강우 데이터를 결합해 농업용수 배분 의사결정 지원
  • 광산·채석장 등 오지 산업 현장: 유선 인터넷이 부재한 환경에서 W5500 유선 백본 + WiFi 보조 구조를 그대로 재사용 가능

한계 및 개선 방향

이 프로젝트는 실시간성 설계(EventGroup/Mutex)와 백필 로직을 상당히 꼼꼼하게 짜뒀습니다. 다만 몇 가지 확장 포인트가 보입니다.

  • 현재 한계: Worst-case 폴링 시간이 30초로 고정되어 있어, 슬레이브가 5개보다 늘어나면 60초 발행 주기 자체가 위협받는 구조적 병목이 있습니다 [추정: 코드 상수 기준 계산, 실측 데이터 없음]. 또한 RTU/TCP 채널 수(각 20개)가 하드코딩되어 있어 대규모 현장에는 구조 변경이 필요합니다.
  • 개선 방향: 슬레이브별 타임아웃을 응답 이력 기반으로 동적 조정하면 폴링 시간을 단축할 수 있습니다. 채널 수 제한은 설정 파일(JSON) 스키마를 배열 기반으로 일반화하면 하드코딩 없이 확장 가능합니다. W5500의 8개 하드웨어 소켓 중 몇 개를 병렬로 활용하는지 문서화되어 있지 않은데, 이를 명시하고 소켓 풀을 늘리면 5호스트 이상의 TCP 폴링도 병렬화할 여지가 있습니다.

FAQ

Q1. 이 구조를 다른 현장에 도입하려면 난이도가 어느 정도인가요? PlatformIO/Arduino 기반이라 진입장벽은 낮지만, RTOS 태스크 동기화(EventGroup/Mutex) 구조를 이해해야 안전하게 커스터마이징할 수 있습니다.

Q2. RS485와 Modbus TCP 슬레이브를 몇 대까지 늘릴 수 있나요? 현재 코드 기준 각각 20채널(5 slave×4 변수)로 하드코딩되어 있습니다. 늘리려면 설정 스키마와 타이밍 상수를 함께 조정해야 합니다.

Q3. WiFi 없이 W5500만으로 운영할 수 있나요? MQTT 업링크가 WiFi 스택에 의존하므로, 현재 코드 구조상 W5500 단독으로 MQTT까지 처리하려면 네트워크 스택 재구성이 필요합니다 [추정].

Q4. SD카드가 고장 나면 어떻게 되나요? README에는 SD 마운트 실패 시의 폴백 로직이 명시되어 있지 않습니다 — 확인 불가.

Q5. MCU를 ESP32-S3가 아닌 다른 칩으로 바꿀 수 있나요? PCNT(엔코더), SD_MMC 4-bit 등 ESP32-S3 전용 페리페럴에 의존하는 부분이 있어, 다른 MCU로 이식하려면 해당 기능의 대체 구현이 필요합니다.


Never Lose a Reading: An ESP32-S3 + W5500 Remote Monitoring System for a Vietnamese Hydropower Station

Summary

This open-source firmware unifies five different sensor interfaces — analog, encoder, digital input, RS485 Modbus RTU, and Modbus TCP — into a single ESP32-S3 board deployed at a Vietnamese hydropower site. WIZnet's W5500 handles the Modbus TCP channels, and an SD-card backfill mechanism automatically buffers data during network outages and replays it once connectivity returns. It's a structural answer to the chronic problem of remote infrastructure sites: a dropped connection shouldn't mean lost data.

Overview

Hydropower stations need to continuously measure reservoir level, inflow/outflow, rainfall, and generation output around the clock. The catch is that most of these sites sit in mountainous, hard-to-reach terrain where wired internet is unreliable or simply absent. WiFi and cellular links drop out routinely, and every dropout that erases data creates a gap in both disaster-response planning and generation scheduling.

esp_thuydien tackles this head-on. A single ESP32-S3 handles analog inputs (4–20mA/0–10V), an encoder, digital input (rain gauge), RS485 Modbus RTU, and Modbus TCP all at once. When connectivity drops, readings are written to SD card as JSON and replayed in order the moment the network comes back. What stands out is that the 60-second realtime publish cycle and the offline backfill replay coexist without collision, coordinated through a mutex.

Why This Matters Now — Vietnam's Mandatory Dam Monitoring Requirements

This kind of system isn't a nice-to-have in Vietnam — it's closer to a legal obligation.

  • Vietnam's Ministry of Industry and Trade Circular 09/2019/TT-BCT requires hydropower dam and reservoir owners to install automatic, online monitoring cameras and instrumentation for discharge operations, and to transmit that data to disaster-response committees, provincial people's committees, the national hydro-meteorological authority, water resource management agencies, and the power regulatory authority.
  • Circular 17/2021/TT-BTNMT requires reservoir water-level data to be transmitted in real time to the national hydrological database.
  • As of April 2026, the Ministry has a draft amendment under public comment that would tighten these requirements further, pushing toward stronger database synchronization and remote-monitoring standards.

A documented real-world case is the Song Ba Ha hydropower plant. Vietnamese trade press (Tạp chí Công Thương, ERAV) reported that the plant connected reservoir level, inflow, discharge, and rainfall sensors along with surveillance cameras to a PLC, automatically pushing data to the national hydrological system over a static IP as part of its digital transformation. That system is built on commercial PLC/SCADA infrastructure, though — whether it uses an ESP32/WIZnet-style embedded open-source stack is not confirmed.

In other words, esp_thuydien itself hasn't been reported in the press as a deployed solution, but the problem it solves — multi-channel measurement, offline backfill, and upstream transmission — maps directly onto a real regulatory need across Vietnam's hydropower sector.

→ Reference: Song Ba Ha digital transformation coverage

Architecture

Four FreeRTOS tasks split responsibilities cleanly through priority levels and synchronization primitives.

Technology Background

Hardware TCP/IP Offloading (W5500)

The W5500 is a TCP/IP Ethernet controller built around a TCP Offload Engine (TOE) — the entire TCP/IP stack runs on dedicated hardware inside the chip. The MCU just exchanges socket registers over SPI; packet handling, retransmission, and checksums are all handled on-chip. In esp_thuydien, this means Modbus TCP polling stays completely decoupled from the WiFi stack's load, so instability on the wireless side never compromises the reliability of the industrial measurement channels.

→ Reference: WIZnet W5500 product page

Modbus RTU vs. Modbus TCP

Modbus RTU exchanges binary frames over an RS485 serial line — simple wiring, strong noise immunity, and a staple of industrial environments. Modbus TCP puts the same data model on top of Ethernet/IP, removing the wiring-distance constraint and letting multiple slaves share a network. This project polls both simultaneously, unifying nearby RS485 instruments and remote IP-based instruments through a single gateway.

MQTT + Offline Backfill Pattern

MQTT's QoS levels guarantee delivery reliability, but QoS is meaningless if the device itself is offline. This project fills that gap with local SD-card storage. Data is tagged "ingest_type": "realtime" while online, and anything accumulated during an outage is replayed afterward as "ingest_type": "backfill". The server calculates timestamp delay and flags anything over five minutes as is_late, so realtime and backfilled data never get confused with each other.

Technical Highlights

  • Worst-case timing pinned as a hard constant: MODBUS_POLL_TIMEOUT_MS is fixed at 30,000ms — the sum of RTU timeout across 5 slaves (5s) and TCP timeout across 5 hosts (25s). Even if that timeout hits, the affected channel is simply marked null and the 60-second publish cycle never slips.
  • EventGroup + Mutex for real-time guarantees: modbusTask runs at a higher priority (3) than loop(), using s_mbEvent to synchronize poll timing and s_pubMutex to prevent realtime and backfill publishes from colliding.
  • A dedicated 32KB stack for OTA: the firmware explicitly accounts for mbedTLS ECDHE handshakes needing more than 28KB of stack, isolating the OTA task with its own stack size — a detail that's easy to overlook and signals real field experience.

Where WIZnet Fits

Model actually used: W5500

  • Connected via SPI (MOSI/MISO/CLK/CS = GPIO 36/38/37/39)
  • Dedicated to polling the Modbus TCP channels (20 channels, 5 slaves × 4 variables)
  • Includes an optimization that merges channels sharing the same host:port into a single TCP connection, cutting down polling time

WiFi handles the MQTT uplink and on-site web configuration, while the W5500 is solely responsible for polling Modbus TCP slaves — a clear division of labor. Even if the wireless network gets shaky, the reliability of the measurement channels themselves is unaffected.

Similar Projects on WIZnet Makers

  • esp32s3-modbus-gateway-gemini — Firmware for a general-purpose industrial gateway that runs ESP32-S3 with W5100S, handling RS485/Modbus RTU, TCP, and WiFi paths simultaneously. Where esp_thuydien is a sensor-side edge device, this one is oriented toward protocol conversion as a gateway. 

→ Project link: https://maker.wiznet.io/matthew/projects/esp32s3-modbus-gateway-gemini/

  • esp32-modbus-mqtt-bridge — ESP32-S3 with W5500 as the primary wired link and WiFi as failover, bridging KinCony industrial relays into Home Assistant. It shares the same networking philosophy as esp_thuydien: wired as default, wireless as backup. 

→ Project link: https://maker.wiznet.io/Lihan__/projects/esp32-modbus-mqtt-bridge/

  • CanhbaongapLongAn — A flood and salinity monitoring station in Long An, Vietnam, built on the same W5500 + RS485 Modbus RTU combination and the same background narrative of remote Vietnamese infrastructure monitoring (same author, scott). 

→ Project link: https://maker.wiznet.io/scott/projects/canhbaongaplongan/

All three projects arrive at the same conclusion: WiFi alone can't guarantee the reliability industrial measurement needs, which is why each one adopts W5500 (or W5100S) as a wired backbone.

ItemThis Project (esp_thuydien)esp32s3-modbus-gateway-geminiesp32-modbus-mqtt-bridgeCanhbaongapLongAn
MCUESP32-S3-WROOM-1-N16ESP32-S3ESP32-S3 (Waveshare)ESP32 (model unconfirmed)
WIZnet chipW5500W5100SW5500W5500
Network structureWiFi (MQTT) + W5500 (TCP), roles separatedWiFi + W5100S, multiple pathsW5500 wired primary + WiFi failoverW5500 + RS485-centric
Target domainHydropower field measurementGeneral-purpose industrial gatewaySmart home (Home Assistant)Public infrastructure (flood/salinity)
Offline storageSD backfill (JSON, auto-replay)UnconfirmedJSON backup/restoreUnconfirmed
OTAHTTPS + SHA256 verificationSupported (details unconfirmed)SupportedUnconfirmed

As the table shows, all four projects share the design philosophy of treating wired Ethernet as the primary network and WiFi as a backup. What sets esp_thuydien apart is that it structures offline recovery as an explicit FreeRTOS task, taking the SD backfill scenario all the way to completion.

Business Value / Use Cases

  • Hydropower reservoir monitoring: the project's primary use case, directly tied to regulatory compliance under Circular 09/2019/TT-BCT
  • Remote water treatment/pumping station telemetry: combine flow meters and level sensors over RS485/TCP with SD backfill to guarantee zero data loss at unmanned facilities
  • Irrigation canal flow management: pair encoder-based flow measurement with rainfall data to support agricultural water allocation decisions
  • Remote industrial sites (mining, quarries, etc.): the same wired-primary/wireless-backup structure applies directly wherever wired internet is unavailable

Limitations and Future Improvements

This project's real-time design (EventGroup/Mutex) and backfill logic are thought through carefully. Still, a few areas leave room for growth.

  • Current limitation: the fixed 30-second worst-case polling window becomes a structural bottleneck if the slave count grows beyond five, threatening the 60-second publish cycle itself [Inferred: based on the code's fixed constants, no measured data available]. The channel counts for RTU/TCP (20 each) are also hardcoded, requiring structural changes for larger deployments.
  • Improvement direction: dynamically adjusting per-slave timeouts based on response history could shrink overall polling time. The channel-count ceiling could be removed by generalizing the config file schema to an array-based structure. The documentation also doesn't specify how many of the W5500's eight hardware sockets are used in parallel — clarifying this and expanding the socket pool would open the door to parallelizing TCP polling across more than five hosts.

FAQ

Q1. How difficult would it be to deploy this architecture at a different site? The PlatformIO/Arduino foundation keeps the barrier to entry low, but safely customizing the RTOS task synchronization (EventGroup/Mutex) requires understanding that structure first.

Q2. How many RS485 and Modbus TCP slaves can this scale to? The current code hardcodes 20 channels each (5 slaves × 4 variables). Scaling beyond that requires adjusting both the configuration schema and the timing constants together.

Q3. Can it run on W5500 alone, without WiFi? Since the MQTT uplink currently depends on the WiFi stack, running MQTT over W5500 alone would require restructuring the networking stack as it stands [Inferred].

Q4. What happens if the SD card fails? The README doesn't specify a fallback for SD mount failure — unconfirmed.

Q5. Can the MCU be swapped for something other than ESP32-S3? Parts of the firmware depend on ESP32-S3-specific peripherals like PCNT (for the encoder) and 4-bit SD_MMC, so porting to a different MCU would require replacing those features.

 

Documents
  • git

Comments Write