Implement MODBUS TCP Server with STM32 Cortex-M4 MCU
Rewatch our session with IoT expert Umesh Lokhande to learn how to implement MODBUS TCP Server communication using WIZnet W5500 and STM32 MCU.
This content was written by DevHeads on the Youtube.
Original link: https://www.youtube.com/watch?v=6SOY0lRozpQ
When Should You Read This?
This content is most useful if you are:
Evaluating whether to implement Modbus TCP instead of Modbus RTU
Designing an industrial Ethernet device using STM32
Considering whether to use hardware TCP/IP offload (W5500) or a software stack (LwIP)
Building a Modbus-compatible device that must operate on TCP port 502
Migrating from serial-based PLC communication to Ethernet-based architecture
It is particularly relevant when:
You need deterministic wired communication rather than Wi-Fi
MCU RAM/Flash resources are limited
You want to reduce firmware complexity related to TCP state handling
You are integrating with existing SCADA or PLC systems
If you are in the early architecture phase of an industrial embedded project, this walkthrough provides a practical reference implementation.
Summary
This project demonstrates how to implement a Modbus TCP server on an STM32 Cortex-M4 microcontroller using the WIZnet W5500 Ethernet controller. The STM32 handles Modbus protocol logic and memory mapping, while the W5500 provides hardware TCP/IP offload over SPI, enabling stable communication on TCP port 502 without burdening the MCU with a software network stack.
Understanding Modbus Before Implementation
What Is Modbus?
Modbus is an industrial communication protocol originally introduced in 1979 by Modicon (now Schneider Electric). It was designed for programmable logic controllers (PLCs) to communicate with sensors, actuators, and supervisory systems.
It remains one of the most widely adopted industrial field protocols due to:
Simple request/response structure
Open and royalty-free specification
Deterministic polling model
Easy integration into PLC and SCADA environments
Modbus RTU vs Modbus TCP
| Feature | Modbus RTU | Modbus TCP |
|---|---|---|
| Physical Layer | RS-485 / Serial | Ethernet |
| Framing | Binary + CRC | TCP/IP + MBAP header |
| Error Check | CRC (16-bit) | TCP checksum |
| Port | N/A | 502 |
| Typical Use | Field bus networks | Industrial Ethernet networks |
Modbus TCP removes the serial framing and CRC, replacing them with:
Ethernet transport
TCP session management
MBAP (Modbus Application Protocol) header
Modbus TCP Frame Structure
Each Modbus TCP packet contains:
Transaction Identifier (2 bytes)
Protocol Identifier (2 bytes, always 0 for Modbus)
Length field
Unit Identifier
Function Code
Data field
Unlike RTU, there is no CRC because TCP/IP already ensures data integrity.
Modbus Memory Model
Modbus abstracts device data into four logical memory areas:
| Memory Type | Access | Size | Typical Use |
|---|---|---|---|
| Coils | Read/Write | 1-bit | Digital outputs |
| Discrete Inputs | Read-only | 1-bit | Digital inputs |
| Input Registers | Read-only | 16-bit | Sensor values |
| Holding Registers | Read/Write | 16-bit | Configuration, analog outputs |
In embedded implementations, these areas are typically mapped to:
GPIO states
ADC readings
Configuration variables
Control parameters
Understanding this memory abstraction is critical before writing firmware.
What the Project Does
The system turns an STM32 MCU into a Modbus TCP server that communicates with a PC-based Modbus TCP client (e.g., Simply Modbus TCP).
System Architecture
MCU: STM32 Cortex-M4
Ethernet Controller: W5500 (SPI interface)
Client Tool: Modbus TCP client software
Protocol: Modbus TCP over Ethernet (Port 502)
Functional Flow
Client sends Modbus TCP request to STM32 server.
W5500 receives Ethernet frame and handles TCP session.
STM32 reads payload via SPI.
Firmware parses:
Transaction ID
Unit ID
Function Code
Corresponding memory area is accessed:
Coils (1-bit output control)
Discrete Inputs
Input Registers
Holding Registers
Response frame is constructed and transmitted back via W5500.
Example use cases demonstrated:
LED ON/OFF using Coil register
Reading/Writing "Hello World" string via Holding Register
Where WIZnet Fits
WIZnet Product: W5500
The W5500 acts as a hardwired TCP/IP offload engine between the STM32 and the Ethernet network.
Why It Matters in This Project
Modbus TCP requires:
Reliable TCP session handling
Deterministic response timing
Continuous socket management
Port 502 listening
Instead of running a software TCP/IP stack (e.g., LwIP), the W5500:
Implements hardware TCP/IP
Supports up to 8 simultaneous sockets
Provides 32KB internal TX/RX buffer
Communicates via SPI (up to 80 MHz)
Practical Impact
MCU RAM usage remains low
CPU cycles are reserved for Modbus logic
No TCP retransmission logic required in firmware
Stable industrial Ethernet communication
For industrial protocols like Modbus TCP, deterministic wired Ethernet is typically preferred over Wi-Fi due to lower jitter and higher link reliability.
Implementation Notes
Since the original video does not provide a public repository, the following is a conceptual integration example based on the WIZnet ioLibrary.
Conceptual integration example based on WIZnet ioLibrary
#include "socket.h"
// SPI callback registration
reg_wizchip_spi_cbfunc(spi_read, spi_write);
// Initialize internal TX/RX buffers (2KB per socket example)
uint8_t txsize[8] = {2,2,2,2,2,2,2,2};
uint8_t rxsize[8] = {2,2,2,2,2,2,2,2};
wizchip_init(txsize, rxsize);
// Configure static IP
wiz_NetInfo netinfo = {
.mac = {0x00,0x08,0xDC,0x11,0x22,0x33},
.ip = {192,168,0,100},
.sn = {255,255,255,0},
.gw = {192,168,0,1}
};
wizchip_setnetinfo(&netinfo);
// Open Modbus TCP server socket (Port 502)
socket(0, Sn_MR_TCP, 502, 0);
listen(0);
Why This Matters
socket() opens TCP port 502 required by Modbus TCP.
listen() puts the W5500 into server mode.
STM32 only processes payload via recv() / send().
TCP state machine is fully managed by hardware.
This separation simplifies firmware architecture and improves reliability.
Practical Tips / Pitfalls
Ensure SPI clock stability (avoid marginal signal integrity at high speed).
Always verify PHY link status before opening socket.
Use static IP during debugging before enabling DHCP.
Allocate socket buffer sizes carefully if multiple connections are expected.
Implement timeout handling in Modbus request parsing.
Validate Function Code before memory access to prevent invalid register access.
Use hardware watchdog in case of unexpected TCP state lock.
FAQ
Q: Why use W5500 instead of LwIP on STM32?
A: W5500 provides hardware TCP/IP offload, eliminating the need for a software stack like LwIP. This reduces RAM usage and CPU load, allowing the STM32 to focus on deterministic Modbus processing.
Q: How is W5500 connected to STM32?
A: It connects via SPI (MOSI, MISO, SCK, CS) plus optional INT and RESET pins. Only four SPI lines are required for full TCP/IP communication.
Q: What role does W5500 play in this Modbus project?
A: It manages TCP sessions on port 502, handles retransmissions, buffering, and Ethernet framing. The STM32 only processes Modbus protocol logic.
Q: Can beginners implement this system?
A: Intermediate embedded knowledge is required, including SPI configuration, TCP server concepts, and Modbus memory mapping. Prior STM32CubeIDE experience is recommended.
Q: How does this compare to using Wi-Fi modules?
A: Wired Ethernet via W5500 provides deterministic latency and higher link stability. Wi-Fi introduces variable latency and interference, which may not be suitable for industrial Modbus networks.
About the Author: DevHeads
The content appears to be produced by DevHeads, a technical YouTube channel focused on embedded systems and industrial communication topics such as Modbus, STM32 development, and Ethernet integration.
From the implementation style shown in the video:
The project demonstrates practical firmware-level integration rather than theoretical explanation.
The Modbus TCP frame structure is correctly described, including MBAP header elements.
Standard industrial conventions such as TCP port 502 and register mapping are followed.
The system demonstrates working client-server validation using a Modbus TCP testing tool.
Although no public repository or formal organizational affiliation is provided, the implementation reflects hands-on embedded development experience, particularly in:
STM32 firmware development
Industrial protocol handling
Ethernet-based communication systems
For engineers evaluating Modbus TCP implementation approaches, this content serves as a practical applied reference rather than an academic or standards-level deep dive.
