Server_based_Relay_control_W5500
A complete IoT relay control solution featuring STM32 firmware with W5500, a Node.js TCP/HTTP server, and a web admin dashboard.
0
Project description
Server-Based Relay Control System β Industrial-Grade Remote Switching with a Web Dashboard
#RelayControl #IoT #SmartBuilding #TOE-TCP #STM32 #W5500 #Node.js #WebDashboard #JSON-over-TCP #RemoteControl
π Individual hobby/learning project β STM32F103 + W5500 firmware + Node.js backend + web dashboard full-stack Firmware confirmed on STM32F103C8; TCP socket mode verified in
app_relay.c
01 β What is this project?
Flipping a relay remotely sounds simple β until you need it to be reliable, auditable, and manageable from any browser without installing anything. Most DIY relay solutions stop at "send a UDP packet, toggle a pin." There is no acknowledgement, no log of who turned what on or when, and no way to see the current state from a dashboard.
This project delivers the full stack: an STM32F103 firmware node connects outward to a central Node.js TCP server over W5500 Ethernet, receives JSON commands, controls a physical relay, and sends back acknowledgements. The Node.js backend stores device state, writes timestamped event logs, and exposes REST endpoints to a browser-based admin dashboard. The result is a relay controller that behaves less like a hobby gadget and more like a managed IoT device β with heartbeat monitoring, authentication, and a live audit trail.
02 β Why Networked Relay Control?
π· The Gap Between "Smart" and "Managed"
Consumer smart plugs use proprietary cloud APIs that disappear when the vendor shuts down, block local-only operation, and offer no audit log. Industrial relay controllers with proper management are expensive and overcomplicated for small deployments. This project sits in the middle: fully local, fully open, REST-accessible, and log-keeping β without proprietary cloud dependency.
π· Reliability Through TCP + Heartbeat
The system uses a persistent TCP connection with a 5-second heartbeat ({"type":"hb"}). If the connection drops, the firmware detects SOCK_ESTABLISHED loss and automatically reconnects. The server marks the device online: false on socket close. This closed-loop availability model means the dashboard always reflects actual device state, not stale cache.
π· Full-Stack in One Repository
Firmware (C/STM32), backend (Node.js), and frontend (HTML/CSS/JS) coexist in a single repo with clear separation. Any developer can clone, configure two IP addresses, and have the system running end-to-end within minutes. The build dependencies (npm install, STM32CubeIDE) are standard and documented.
03 β System Architecture

04 β Why W5500?
π· TOE TCP Socket Mode β Client-Initiated Persistent Connection
This project uses W5500's hardware TCP socket mode (Sn_MR_TCP) in an unusual pattern: the STM32 acts as the TCP client, initiating a persistent outbound connection to the Node.js server. This is the correct topology for a device behind NAT or in a network where inbound connections to the MCU are not desirable.
// From Core/Src/app_relay.c β confirmed socket(RELAY_SOCKET, Sn_MR_TCP, 5000, 0); // local port 5000 connect(RELAY_SOCKET, server_ip, SERVER_PORT); // connect to server :9000 send_hello(); // {"type":"hello","deviceId":"relay-f105-01"} send_status(); // {"type":"status","relay1":"off"}W5500's TOE handles TCP state, retransmission, and ACK entirely in hardware. The STM32 loop calls getSn_SR() to check connection health and recv() to get incoming commands β no TCP stack in firmware code at all.
π· PHY Link Monitoring β Hardware-Level Connectivity Awareness
The firmware polls wizphy_getphylink() during initialization and waits up to 2 seconds for the physical Ethernet link to come up before attempting any socket operations. This prevents connection attempts before the cable is live β a common failure mode in DIY projects that skip PHY state checking.
if (WaitForPhyLink(PHY_LINK_TIMEOUT_MS)) UART_Print("LAN OK\r\n"); else UART_Print("LAN FAIL\r\n");W5500's embedded PHY status register makes this one function call. On a raw MAC+external PHY design, this would require reading PHY registers over MDIO.
π· Auto-Reconnect Loop β Always-Connected Device Behavior
void socket_loop(void) { if (getSn_SR(RELAY_SOCKET) != SOCK_ESTABLISHED) { close(RELAY_SOCKET); HAL_Delay(1000); socket_connect(); // re-open Sn_MR_TCP socket and reconnect return; } // recv() β parse_cmd() }Every main loop iteration checks TCP connection health. Drop detected β reconnect within 1 second. The server-side socket.on("close") handler marks the device offline instantly. Together these form a closed-loop availability model with no manual intervention needed.
π· Static IP β Deterministic Network Identity
NETINFO_STATIC, IP 192.168.31.50. The device is reachable immediately after power-on. No DHCP boot delay, no address change surprises. For a relay node in a fixed-location deployment, static IP is always the right choice.
π· Verified Evidence β
socket(RELAY_SOCKET, Sn_MR_TCP, 5000, 0)confirmed inapp_relay.cconnect(),send(),recv(),getSn_SR()confirmed in application codewizchip_init(),wizchip_setnetinfo(),getVERSIONR()confirmed β chip version read at bootWaitForPhyLink()withwizphy_getphylink()confirmed β PHY link gate before socket- Serial debug log (
teraterm_logs.txt) included in repo β boot sequence captured on real hardware Server_based_Relay_controll.pdfincluded β project documentation
05 β Key Components
π WIZnet W5500 β TCP TOE Mode (Sn_MR_TCP), Client Mode
Hardware TCP/IP offload over SPI1. The STM32 opens an outbound TCP connection to the Node.js server on port 9000. JSON messages flow over this persistent socket. No TCP stack in firmware β W5500 handles it in silicon.
π§ STM32F103C8T6
72 MHz Cortex-M3. SPI1 drives W5500 (CS: PA4, RST: PB1). PB5 drives the relay output (active high). UART1 outputs debug messages to Tera Term. STM32CubeIDE project included (.ioc + .cproject).
π₯οΈ Node.js Backend (server.js)
Single-file server running both TCP listener (:9000, device side) and HTTP server (:8080, dashboard side). JSON line-protocol parsing, session-based authentication (PBKDF2 password hashing), JSON file datastore for users/devices/logs, REST API for dashboard control. No external database needed.
π Web Admin Dashboard (frontend/)
Static HTML/CSS/JS dashboard. Login β overview summary β device list β relay toggle β per-device event log. Fully functional from any browser with no installation. Reads/writes via REST API to the Node.js backend.
06 β Application Scenarios
01. Smart Building Subsystem
Building automation engineers deploy STM32+W5500 relay nodes to control HVAC dampers, lighting circuits, or door locks. The central Node.js server aggregates all nodes into a unified dashboard, with timestamped logs satisfying basic audit requirements for facilities management.
02. Lab Equipment Power Management
A research lab installs one relay node per instrument rack. The admin dashboard shows which instruments are powered at a glance. Instruments can be toggled remotely without walking the lab. The event log provides a record of power cycling β useful for troubleshooting instrument failures correlated to power events.
03. Industrial Pilot Line Control
A small manufacturing line uses relay nodes to enable/disable conveyor motors or pneumatic valves from a central HMI browser interface. The heartbeat monitoring ensures the operator knows immediately if a node loses network connection β critical for safety-aware process control.
04. Home Automation Gateway
A maker installs relay nodes behind mains switches for lights, fans, or irrigation valves. The self-hosted Node.js server (Raspberry Pi or NAS) provides local-only control with no cloud dependency. The web dashboard is accessible from any device on the home network.
Conclusion
This project demonstrates that W5500's hardware TCP offload turns a bare STM32F103 into a fully managed IoT relay node β complete with JSON protocol, heartbeat monitoring, REST dashboard, and event logging.
- β
W5500 TCP TOE client mode confirmed β
socket(Sn_MR_TCP)+connect()inapp_relay.c - β
PHY link gate before socket β
wizphy_getphylink()polling confirmed - β Auto-reconnect loop β connection health checked every main loop iteration
- β JSON line-protocol bidirectional: hello / status / command / ack / heartbeat
- β Node.js backend with authentication, REST API, and persistent event log (up to 5,000 entries)
- β Browser-based admin dashboard β no client installation, works from any device
- β
Serial boot log (
teraterm_logs.txt) captured on real hardware - β Full-stack in one repo: firmware + backend + frontend, 3-commit clean history
A relay, an STM32, and an Ethernet jack. This kind of project also uses W5500.
07 β Similar Projects on WIZnet Makers
Several projects on the platform address the same relay-over-Ethernet space.
Relay control via HTTP Rest Protocol (WIZnet official) demonstrates the concept using HTTP REST directly on the device. Simpler topology β no central server, browser talks directly to the MCU. β https://maker.wiznet.io/WIZnet/projects/relay-control-via-http-rest-protocol/
ESP32 (38-pin) + W5500: Offline LAN Relay Control with a Simple Web Server (sophia, 2026) uses ESP32+W5500 with an embedded web server β no separate backend server, browser hits the MCU directly. β https://maker.wiznet.io/sophia/projects/esp32-38-pin-w5500-offline-lan-relay-control-with-a-simple-web-server/
8 Channel Ethernet Relay Controller (Alan, 2025) scales up to 8 channels with PoE support β hardware-focused, no software dashboard. β https://maker.wiznet.io/Alan/projects/8-channel-ethernet-relay-controller-support-poe-and-usb/
| This Project | HTTP REST (WIZnet) | ESP32 Web Server | 8-Ch PoE Controller | |
|---|---|---|---|---|
| MCU | STM32F103 | β | ESP32 | β |
| W5500 role | TCP KM channel | HTTP server | On-board | On-board |
| Protocol | JSON over TCP | HTTP REST | HTTP (embedded) | β |
| Central server | β Node.js | β | β | β |
| Web dashboard | β separate | β (on MCU) | β (on MCU) | β |
| Auth + logging | β | β | β | β |
| Relay channels | 1 | varies | varies | 8 |
| Heartbeat / reconnect | β | β | β | β |
The key differentiator of this project is the centralized server architecture with authentication and logging β the only one in this group that treats the relay node as a managed device rather than a standalone controller. The trade-off is deployment complexity: Node.js backend must run separately. The insight is that as relay deployments grow beyond one or two nodes, centralized management becomes essential β and this project is the only one in the ecosystem already built for that.
Q&A
Q: Why does the STM32 connect outward to the server rather than the server connecting to the STM32? A: Client-initiated TCP is the correct model for devices behind NAT or on dynamic IPs. The device always knows the server's fixed IP; the server never needs to know the device's IP in advance. The hello message carries the device ID, letting the server register any device that connects.
Q: Why JSON over raw TCP rather than HTTP or MQTT? A: JSON over newline-delimited TCP is the lightest full-featured option for an STM32F103 with 64KB flash. HTTP adds request/response framing overhead; MQTT requires a broker. The Node.js server can parse newline-delimited JSON with three lines of code. For a single-channel prototype, this is the right trade-off.
Q: Can the system scale to multiple relay nodes? A: Yes by design. The deviceSockets Map and devices.json datastore on the server side are keyed by deviceId. Each firmware node just needs a unique DEVICE_ID string and the same server IP. The dashboard automatically lists all connected devices.
μλ² κΈ°λ° λ¦΄λ μ΄ μ μ΄ μμ€ν β μΉ λμ보λλ₯Ό κ°μΆ μ°μ κΈ μ격 μ€μμΉ
#릴λ μ΄μ μ΄ #IoT #μ€λ§νΈλΉλ© #TOE-TCP #STM32 #W5500 #Node.js #μΉλμ보λ #JSON-over-TCP #μ격μ μ΄
π κ°μΈ μ·¨λ―Έ/νμ΅ νλ‘μ νΈ β STM32F103 + W5500 νμ¨μ΄ + Node.js λ°±μλ + μΉ λμ보λ νμ€ν STM32F103C8 νμ¨μ΄ νμΈ μλ£;
app_relay.cμμ TCP μμΌ λͺ¨λ κ²μ¦λ¨
01 β μ΄ νλ‘μ νΈλ 무μμΈκ°?
릴λ μ΄λ₯Ό μ격μΌλ‘ μΌκ³ λλ κ²μ λ¨μν΄ λ³΄μΈλ€ β μ λ’°μ±, κ°μ¬ μΆμ , λΈλΌμ°μ μ΄λμλ μ κ·Όμ΄ νμν λκΉμ§λ. λλΆλΆμ DIY 릴λ μ΄ μ루μ μ "UDP ν¨ν· νλ 보λ΄κ³ ν ν κΈ"μμ λ©μΆλ€. μλ΅ νμΈλ μκ³ , λκ° μΈμ 무μμ μΌ°λμ§ κΈ°λ‘λ μμΌλ©°, λμ보λμμ νμ¬ μνλ₯Ό λ³Ό λ°©λ²λ μλ€.
μ΄ νλ‘μ νΈλ νμ€νμ μ 곡νλ€: STM32F103 νμ¨μ΄ λ Έλκ° W5500 μ΄λλ·μ ν΅ν΄ μ€μ Node.js TCP μλ²μ μ μνκ³ , JSON λͺ λ Ήμ μμ νκ³ , 물리 릴λ μ΄λ₯Ό μ μ΄νκ³ , νμΈ μλ΅μ λλ €λ³΄λΈλ€. Node.js λ°±μλλ λλ°μ΄μ€ μνλ₯Ό μ μ₯νκ³ , νμμ€ν¬νκ° μ°ν μ΄λ²€νΈ λ‘κ·Έλ₯Ό κΈ°λ‘νλ©°, λΈλΌμ°μ κΈ°λ° κ΄λ¦¬ λμ보λμ REST μλν¬μΈνΈλ₯Ό μ 곡νλ€. κ²°κ³Όλ¬Όμ μ·¨λ―Έ κ°μ ―λ³΄λ€ κ΄λ¦¬ν IoT λλ°μ΄μ€μ κ°κΉλ€ β ννΈλΉνΈ λͺ¨λν°λ§, μΈμ¦, μ€μκ° κ°μ¬ λ‘κ·ΈκΉμ§.
02 β μ λ€νΈμν¬ λ¦΄λ μ΄ μ μ΄μΈκ°?
π· "μ€λ§νΈ"μ "κ΄λ¦¬λ¨"μ κ°κ·Ή
μλΉμμ© μ€λ§νΈ νλ¬κ·Έλ λ²€λκ° μλΉμ€λ₯Ό μ’ λ£νλ©΄ μ¬λΌμ§λ λ μ ν΄λΌμ°λ APIλ₯Ό μ¬μ©νκ³ , λ‘컬 μ μ© λμμ λ§μΌλ©°, κ°μ¬ λ‘κ·Έλ₯Ό μ 곡νμ§ μλλ€. μ λλ‘ λ κ΄λ¦¬ κΈ°λ₯μ κ°μΆ μ°μ μ© λ¦΄λ μ΄ μ»¨νΈλ‘€λ¬λ μκ·λͺ¨ λ°°ν¬μ κ³Όνκ² λ³΅μ‘νκ³ λΉμΈλ€. μ΄ νλ‘μ νΈλ κ·Έ μ€κ°μ μμΉνλ€: μμ λ‘컬, μμ μ€ν, REST μ κ·Ό κ°λ₯, λ‘κ·Έ 보쑴 β λ μ ν΄λΌμ°λ μμ‘΄ μμ΄.
π· TCP + ννΈλΉνΈλ₯Ό ν΅ν μ λ’°μ±
μμ€ν
μ 5μ΄ ννΈλΉνΈ({"type":"hb"})μ ν¨κ» μμ TCP μ°κ²°μ μ¬μ©νλ€. μ°κ²°μ΄ λκΈ°λ©΄ νμ¨μ΄κ° SOCK_ESTABLISHED μμ€μ κ°μ§νκ³ μλμΌλ‘ μ¬μ μνλ€. μλ²λ μμΌ μ’
λ£ μ λλ°μ΄μ€λ₯Ό μ¦μ online: falseλ‘ νμνλ€. μ΄ ν루ν κ°μ©μ± λͺ¨λΈμ λμ보λκ° νμ μ€μ λλ°μ΄μ€ μνλ₯Ό λ°μνλλ‘ λ³΄μ₯νλ€.
π· λ¨μΌ μ μ₯μμ νμ€ν
νμ¨μ΄(C/STM32), λ°±μλ(Node.js), νλ‘ νΈμλ(HTML/CSS/JS)κ° λͺ νν λΆλ¦¬ κ΅¬μ‘°λ‘ νλμ μ μ₯μμ 곡쑴νλ€. κ°λ°μ λꡬλ ν΄λ‘ νκ³ IP μ£Όμ λ κ°λ₯Ό μ€μ νλ©΄ λͺ λΆ μμ μλ-ν¬-μλλ‘ λμνλ μμ€ν μ μ»μ μ μλ€.
03 β μμ€ν μν€ν μ²

04 β μ W5500μΈκ°?
π· TOE TCP μμΌ λͺ¨λ β ν΄λΌμ΄μΈνΈ κ°μ μμ μ°κ²°
μ΄ νλ‘μ νΈλ W5500μ **νλμ¨μ΄ TCP μμΌ λͺ¨λ(Sn_MR_TCP)**λ₯Ό λ
νΉν ν¨ν΄μΌλ‘ μ¬μ©νλ€: STM32κ° TCP ν΄λΌμ΄μΈνΈλ‘μ Node.js μλ²μ μμλ°μ΄λ μ°κ²°μ κ°μνλ€. NAT λ€μ μλ λλ°μ΄μ€λ μΈλ°μ΄λ μ°κ²°μ΄ λ°λμ§νμ§ μμ λ€νΈμν¬μμ μ¬λ°λ₯Έ ν ν΄λ‘μ§λ€.
// Core/Src/app_relay.c μμ νμΈ socket(RELAY_SOCKET, Sn_MR_TCP, 5000, 0); // λ‘컬 ν¬νΈ 5000 connect(RELAY_SOCKET, server_ip, SERVER_PORT); // μλ² :9000μΌλ‘ μ°κ²° send_hello(); // {"type":"hello","deviceId":"relay-f105-01"} send_status(); // {"type":"status","relay1":"off"}W5500μ TOEκ° TCP μν, μ¬μ μ‘, ACKλ₯Ό νλμ¨μ΄μμ μ λΆ μ²λ¦¬νλ€. STM32 루νλ getSn_SR()λ‘ μ°κ²° μνλ₯Ό νμΈνκ³ recv()λ‘ λͺ
λ Ήμ μμ ν λΏμ΄λ€ β νμ¨μ΄ μ½λμ TCP μ€νμ΄ μ ν μλ€.
π· PHY λ§ν¬ λͺ¨λν°λ§ β νλμ¨μ΄ λ 벨 μ°κ²° μΈμ
νμ¨μ΄λ μ΄κΈ°ν μ€ wizphy_getphylink()λ₯Ό ν΄λ§ν΄ μμΌ λμ μλ μ μ΅λ 2μ΄κ° 물리 μ΄λλ· λ§ν¬κ° μ¬λΌμ€κΈ°λ₯Ό κΈ°λ€λ¦°λ€. μΌμ΄λΈμ΄ μ°κ²°λκΈ° μ μ μμΌ λμμ μλνλ DIY νλ‘μ νΈμ νν μ€ν¨ λͺ¨λλ₯Ό λ°©μ§νλ€. W5500μ λ΄μ₯ PHY μν λ μ§μ€ν°κ° μ΄λ₯Ό ν¨μ νΈμΆ νλλ‘ κ°λ₯νκ² νλ€.
π· μλ μ¬μ μ 루ν β νμ μ°κ²°λ λλ°μ΄μ€ λμ
λ©μΈ 루ν λ§€ λ°λ³΅λ§λ€ TCP μ°κ²° μνλ₯Ό νμΈνλ€. μ°κ²° λκΉ κ°μ§ β 1μ΄ λ΄ μ¬μ μ. μλ² μΈ‘ socket.on("close") νΈλ€λ¬κ° λλ°μ΄μ€λ₯Ό μ¦μ μ€νλΌμΈμΌλ‘ νμνλ€. μ΄ λ κ°μ§κ° ν©μ³μ Έ μλ κ°μ
μλ ν루ν κ°μ©μ± λͺ¨λΈμ νμ±νλ€.
π· Static IP β κ²°μ λ‘ μ λ€νΈμν¬ μ μ
NETINFO_STATIC, IP 192.168.31.50. μ μ ν¬μ
μ§ν μ¦μ λλ¬ κ°λ₯. DHCP λΆν
μ§μ° μμ, μ£Όμ λ³κ²½ μμ. κ³ μ μμΉ λ°°ν¬μ 릴λ μ΄ λ
Έλμμ νμ μ¬λ°λ₯Έ μ νμ΄λ€.
π· κ²μ¦λ μ¦κ±° β
socket(RELAY_SOCKET, Sn_MR_TCP, 5000, 0)βapp_relay.cμμ μ§μ νμΈconnect(),send(),recv(),getSn_SR()β μ ν리μΌμ΄μ μ½λμμ νμΈwizchip_init(),wizchip_setnetinfo(),getVERSIONR()β λΆν μ μΉ© λ²μ μ½κΈ° νμΈWaitForPhyLink()μwizphy_getphylink()β μμΌ μ PHY λ§ν¬ κ²μ΄νΈ νμΈteraterm_logs.txtβ μ€μ νλμ¨μ΄ λΆν μνμ€ μλ¦¬μΌ λ‘κ·Έ μ μ₯μμ ν¬ν¨Server_based_Relay_controll.pdfβ νλ‘μ νΈ λ¬Έμ ν¬ν¨
05 β ν΅μ¬ μ»΄ν¬λνΈ
π WIZnet W5500 β TCP TOE λͺ¨λ (Sn_MR_TCP), ν΄λΌμ΄μΈνΈ λͺ¨λ
SPI1 λ²μ€μ νλμ¨μ΄ μ€νλ‘λ TCP/IP. STM32κ° μλ² ν¬νΈ 9000μΌλ‘ μμλ°μ΄λ TCP μ°κ²°μ κ°μ. JSON λ©μμ§κ° μ΄ μμ μμΌμΌλ‘ νλ¦. νμ¨μ΄μ TCP μ€ν μμ β W5500μ΄ μ€λ¦¬μ½μμ μ²λ¦¬.
π§ STM32F103C8T6
72 MHz Cortex-M3. SPI1μ΄ W5500 ꡬλ (CS: PA4, RST: PB1). PB5κ° λ¦΄λ μ΄ μΆλ ₯ ꡬλ (Active High). UART1μ΄ Tera Term λλ²κ·Έ μΆλ ₯. STM32CubeIDE νλ‘μ νΈ ν¬ν¨ (.ioc + .cproject).
π₯οΈ Node.js λ°±μλ (server.js)
TCP 리μ€λ(:9000, λλ°μ΄μ€ μΈ‘)μ HTTP μλ²(:8080, λμ보λ μΈ‘)λ₯Ό λͺ¨λ μ€ννλ λ¨μΌ νμΌ μλ². JSON λΌμΈ νλ‘ν μ½ νμ±, μΈμ
κΈ°λ° μΈμ¦(PBKDF2 ν¨μ€μλ ν΄μ±), μ¬μ©μ/λλ°μ΄μ€/λ‘κ·Έλ₯Ό μν JSON νμΌ λ°μ΄ν°μ€ν μ΄, λμ보λ μ μ΄μ© REST API. μΈλΆ λ°μ΄ν°λ² μ΄μ€ λΆνμ.
π μΉ κ΄λ¦¬ λμ보λ (frontend/)
μ μ HTML/CSS/JS λμ보λ. λ‘κ·ΈμΈ β κ°μ μμ½ β λλ°μ΄μ€ λͺ©λ‘ β 릴λ μ΄ ν κΈ β λλ°μ΄μ€λ³ μ΄λ²€νΈ λ‘κ·Έ. μ€μΉ μμ΄ μ΄λ λΈλΌμ°μ μμλ μμ λμ. Node.js λ°±μλ REST APIλ‘ μ½κΈ°/μ°κΈ°.
06 β νμ© μλ리μ€
01. μ€λ§νΈ λΉλ© μλΈμμ€ν
λΉλ© μλν μμ§λμ΄κ° HVAC λνΌ, μ‘°λͺ νλ‘, λμ΄λ½ μ μ΄λ₯Ό μν΄ STM32+W5500 릴λ μ΄ λ Έλλ₯Ό λ°°ν¬νλ€. μ€μ Node.js μλ²κ° λͺ¨λ λ Έλλ₯Ό ν΅ν© λμ보λλ‘ μ§κ³νλ©°, νμμ€ν¬ν λ‘κ·Έκ° μμ€ κ΄λ¦¬μ κΈ°λ³Έ κ°μ¬ μ건μ μΆ©μ‘±νλ€.
02. μ°κ΅¬μ€ μ₯λΉ μ μ κ΄λ¦¬
μ°κ΅¬μ€μ΄ μ₯λΉ λλ§λ€ 릴λ μ΄ λ Έλλ₯Ό μ€μΉνλ€. κ΄λ¦¬μ λμ보λκ° μ΄λ€ μ₯λΉμ μ μμ΄ λ€μ΄μ μλμ§ νλμ 보μ¬μ€λ€. μ₯λΉλ₯Ό 물리μ μΌλ‘ μ΄λνμ§ μκ³ μ격μΌλ‘ μ μμ ν κΈν μ μλ€. μ΄λ²€νΈ λ‘κ·Έκ° μ μ μ¬μ΄ν΄λ§ κΈ°λ‘μ μ 곡νλ€.
03. μ°μ μ© νμΌλΏ λΌμΈ μ μ΄
μκ·λͺ¨ μ μ‘° λΌμΈμ΄ 릴λ μ΄ λ Έλλ₯Ό μ¬μ©ν΄ μ»¨λ² μ΄μ΄ λͺ¨ν°λ 곡μ λ°ΈλΈλ₯Ό μ€μ HMI λΈλΌμ°μ μΈν°νμ΄μ€μμ νμ±ν/λΉνμ±ννλ€. ννΈλΉνΈ λͺ¨λν°λ§μ΄ λ Έλκ° λ€νΈμν¬ μ°κ²°μ μμΌλ©΄ μ΄μμμκ² μ¦μ μλ¦°λ€.
04. ν μ€ν λ©μ΄μ κ²μ΄νΈμ¨μ΄
λ©μ΄μ»€κ° μ‘°λͺ , μ νκΈ°, κ΄κ° λ°ΈλΈμ μ μ μ€μμΉ λ€μ 릴λ μ΄ λ Έλλ₯Ό μ€μΉνλ€. μ체 νΈμ€ν Node.js μλ²(λΌμ¦λ² 리 νμ΄ λλ NAS)κ° ν΄λΌμ°λ μμ‘΄ μμ΄ λ‘컬 μ μ© μ μ΄λ₯Ό μ 곡νλ€.
κ²°λ‘
μ΄ νλ‘μ νΈλ W5500μ νλμ¨μ΄ TCP μ€νλ‘λκ° λ§¨ STM32F103μ JSON νλ‘ν μ½, ννΈλΉνΈ λͺ¨λν°λ§, REST λμ보λ, μ΄λ²€νΈ λ‘κΉ μ κ°μΆ μμ κ΄λ¦¬ν IoT 릴λ μ΄ λ Έλλ‘ μ νμν¨λ€λ κ²μ 보μ¬μ€λ€.
- β
W5500 TCP TOE ν΄λΌμ΄μΈνΈ λͺ¨λ νμΈ β
app_relay.cμμsocket(Sn_MR_TCP)+connect() - β
μμΌ μ PHY λ§ν¬ κ²μ΄νΈ β
wizphy_getphylink()ν΄λ§ νμΈ - β μλ μ¬μ μ 루ν β λ©μΈ 루ν λ§€ λ°λ³΅ μ°κ²° μν νμΈ
- β JSON λΌμΈ νλ‘ν μ½ μλ°©ν₯: hello / status / command / ack / heartbeat
- β μΈμ¦, REST API, μμ μ΄λ²€νΈ λ‘κ·Έ(μ΅λ 5,000건)λ₯Ό κ°μΆ Node.js λ°±μλ
- β λΈλΌμ°μ κΈ°λ° κ΄λ¦¬ λμ보λ β ν΄λΌμ΄μΈνΈ μ€μΉ λΆνμ
- β
μ€μ νλμ¨μ΄μμ μΊ‘μ²ν μλ¦¬μΌ λΆν
λ‘κ·Έ(
teraterm_logs.txt) ν¬ν¨ - β λ¨μΌ μ μ₯μ νμ€ν: νμ¨μ΄ + λ°±μλ + νλ‘ νΈμλ, 3μ»€λ° κΉλν μ΄λ ₯
릴λ μ΄ νλ, STM32, μ΄λλ· μ νλ. μ΄λ° μ’ λ₯μ νλ‘μ νΈλ W5500μ μ¬μ©νλ€.
07 β WIZnet Makers μ μ¬ νλ‘μ νΈ
νλ«νΌμμ κ°μ 릴λ μ΄-over-μ΄λλ· κ³΅κ°μ λ€λ£¨λ νλ‘μ νΈλ€μ΄ λ€μ μ‘΄μ¬νλ€.
Relay control via HTTP Rest Protocol (WIZnet 곡μ)μ HTTP RESTλ₯Ό λλ°μ΄μ€μμ μ§μ μ²λ¦¬νλ€. λ λ¨μν ν ν΄λ‘μ§ β μ€μ μλ² μμ΄ λΈλΌμ°μ κ° MCUμ μ§μ ν΅μ . β https://maker.wiznet.io/WIZnet/projects/relay-control-via-http-rest-protocol/
ESP32 (38-pin) + W5500: Offline LAN Relay Control with a Simple Web Server (sophia, 2026)λ ESP32+W5500κ³Ό λ΄μ₯ μΉ μλ²λ₯Ό μ¬μ©νλ€ β λ³λ λ°±μλ μλ² μμ΄ λΈλΌμ°μ κ° MCUμ μ§μ μ μ. β https://maker.wiznet.io/sophia/projects/esp32-38-pin-w5500-offline-lan-relay-control-with-a-simple-web-server/
8 Channel Ethernet Relay Controller (Alan, 2025)λ PoE μ§μμΌλ‘ 8μ±λκΉμ§ νμ₯νλ€ β νλμ¨μ΄ μ€μ¬, μννΈμ¨μ΄ λμ보λ μμ. β https://maker.wiznet.io/Alan/projects/8-channel-ethernet-relay-controller-support-poe-and-usb/
| μ΄ νλ‘μ νΈ | HTTP REST | ESP32 μΉ μλ² | 8μ±λ PoE | |
|---|---|---|---|---|
| MCU | STM32F103 | β | ESP32 | β |
| W5500 μν | TCP μ μ΄ μ±λ | HTTP μλ² | μ¨λ³΄λ | μ¨λ³΄λ |
| νλ‘ν μ½ | JSON over TCP | HTTP REST | HTTP (λ΄μ₯) | β |
| μ€μ μλ² | β Node.js | β | β | β |
| μΉ λμ보λ | β λΆλ¦¬ν | β (MCU λ΄) | β (MCU λ΄) | β |
| μΈμ¦ + λ‘κΉ | β | β | β | β |
| 릴λ μ΄ μ±λ | 1 | λ€μ | λ€μ | 8 |
| ννΈλΉνΈ/μ¬μ μ | β | β | β | β |
μ΄ νλ‘μ νΈμ ν΅μ¬ μ°¨λ³μ μ μΈμ¦κ³Ό λ‘κΉ μ κ°μΆ μ€μν μλ² μν€ν μ² β 릴λ μ΄ λ Έλλ₯Ό λ 립ν 컨νΈλ‘€λ¬κ° μλ κ΄λ¦¬ν λλ°μ΄μ€λ‘ μ·¨κΈνλ μ μΌν νλ‘μ νΈλ€. νΈλ μ΄λμ€νλ λ°°ν¬ λ³΅μ‘μ±: Node.js λ°±μλκ° λ³λλ‘ μ€νλμ΄μΌ νλ€. μΈμ¬μ΄νΈλ 릴λ μ΄ λ°°ν¬κ° λ Έλ νλ κ°λ₯Ό λμ΄ νμ₯λλ©΄ μ€μν κ΄λ¦¬κ° νμκ° λλ€λ κ²μ΄κ³ , μ΄ νλ‘μ νΈλ μ΄λ―Έ κ·Έκ²μ μν΄ μ€κ³λ μνκ³ λ΄ μ μΌν μ‘΄μ¬λ€.
Q&A
Q: STM32κ° μλ²μ μμλ°μ΄λλ‘ μ°κ²°νλ μ΄μ λ? A: ν΄λΌμ΄μΈνΈ κ°μ TCPκ° NAT λ€μ μκ±°λ λμ IPλ₯Ό κ°μ§ λλ°μ΄μ€μ μ¬λ°λ₯Έ λͺ¨λΈμ΄λ€. λλ°μ΄μ€λ νμ μλ²μ κ³ μ IPλ₯Ό μκ³ μκ³ , μλ²λ λλ°μ΄μ€ IPλ₯Ό 미리 μ νμκ° μλ€. hello λ©μμ§κ° λλ°μ΄μ€ IDλ₯Ό μ λ¬ν΄ μλ²κ° μ μνλ λͺ¨λ λλ°μ΄μ€λ₯Ό λ±λ‘ν μ μκ² νλ€.
Q: HTTPλ MQTT λμ TCP μ JSONμ μ¬μ©ν μ΄μ λ? A: λ΄λΌμΈ κ΅¬λΆ JSON over TCPλ 64KB νλμλ₯Ό κ°μ§ STM32F103μμ κ°μ₯ κ°λ²Όμ΄ μμ κΈ°λ₯ μ΅μ μ΄λ€. HTTPλ μμ²/μλ΅ νλ μ΄λ° μ€λ²ν€λλ₯Ό μΆκ°νκ³ , MQTTλ λΈλ‘μ»€κ° νμνλ€. Node.js μλ²λ μΈ μ€μ μ½λλ‘ λ΄λΌμΈ κ΅¬λΆ JSONμ νμ±ν μ μλ€.
Q: μ¬λ¬ 릴λ μ΄ λ
Έλλ‘ νμ₯λ μ μλ? A: μ€κ³μ κ°λ₯νλ€. μλ² μΈ‘ deviceSockets Mapκ³Ό devices.json λ°μ΄ν°μ€ν μ΄λ deviceIdλ₯Ό ν€λ‘ νλ€. κ° νμ¨μ΄ λ
Έλλ κ³ μ ν DEVICE_ID λ¬Έμμ΄κ³Ό λμΌν μλ² IPλ§ μμΌλ©΄ λλ€. λμ보λκ° μ°κ²°λ λͺ¨λ λλ°μ΄μ€λ₯Ό μλμΌλ‘ λμ΄νλ€.