0
0
Scada-systemsHow-ToBeginner · 4 min read

How Modbus TCP Works in SCADA Systems Explained

In SCADA systems, Modbus TCP works by using Ethernet to connect the SCADA master (client) with field devices (servers) over a network. It sends requests and receives data like sensor readings or control commands using a simple, standardized message format over TCP/IP.
📐

Syntax

The basic syntax of a Modbus TCP message includes a Transaction Identifier, Protocol Identifier, Length, Unit Identifier, Function Code, and Data fields.

Each part has a role:

  • Transaction Identifier: Matches requests and responses.
  • Protocol Identifier: Always 0 for Modbus.
  • Length: Number of bytes following.
  • Unit Identifier: Identifies remote device (usually 1).
  • Function Code: Defines action (read/write).
  • Data: Contains addresses and values.
text
Transaction ID (2 bytes) | Protocol ID (2 bytes) | Length (2 bytes) | Unit ID (1 byte) | Function Code (1 byte) | Data (N bytes)
💻

Example

This example shows a SCADA master reading holding registers from a Modbus TCP device at IP 192.168.1.10 on port 502.

The function code 03 requests to read holding registers starting at address 0x0000, reading 2 registers.

python
import socket

# Modbus TCP request to read 2 holding registers starting at address 0
request = bytes([
    0x00, 0x01,       # Transaction ID
    0x00, 0x00,       # Protocol ID
    0x00, 0x06,       # Length
    0x01,             # Unit ID
    0x03,             # Function Code (Read Holding Registers)
    0x00, 0x00,       # Starting Address Hi, Lo
    0x00, 0x02        # Quantity of Registers Hi, Lo
])

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect(('192.168.1.10', 502))
    s.sendall(request)
    response = s.recv(1024)
    print('Response:', response.hex())
Output
Response: 000100000705010304000a000b
⚠️

Common Pitfalls

  • Wrong port: Modbus TCP uses port 502; using another port causes connection failure.
  • Incorrect function code: Using unsupported codes leads to error responses.
  • Addressing errors: Starting address or quantity out of range causes exceptions.
  • Ignoring TCP framing: Modbus TCP requires proper header fields; missing them breaks communication.
python
## Wrong way: Missing Transaction ID and Protocol ID
wrong_request = bytes([
    0x01,             # Unit ID
    0x03,             # Function Code
    0x00, 0x00,       # Starting Address
    0x00, 0x02        # Quantity
])

## Right way: Include full Modbus TCP header
right_request = bytes([
    0x00, 0x01,       # Transaction ID
    0x00, 0x00,       # Protocol ID
    0x00, 0x06,       # Length
    0x01,             # Unit ID
    0x03,             # Function Code
    0x00, 0x00,       # Starting Address
    0x00, 0x02        # Quantity
])
📊

Quick Reference

FieldDescriptionTypical Value/Notes
Transaction IdentifierMatches request and response0x0001 (increments)
Protocol IdentifierProtocol type0x0000 (Modbus)
LengthNumber of bytes after this fieldUsually 6
Unit IdentifierSlave device ID1 (default)
Function CodeAction to perform0x03 (Read Holding Registers)
DataAddresses and valuesVaries by function

Key Takeaways

Modbus TCP uses Ethernet and TCP/IP to connect SCADA masters with devices using a simple message format.
Each Modbus TCP message has a header with transaction, protocol, length, and unit identifiers before function and data fields.
Common errors include wrong port, missing header fields, and incorrect function codes.
Reading registers involves sending a request with function code 03 and receiving data in the response.
Always use port 502 and follow the Modbus TCP framing to ensure reliable communication.