Communication
PLC Serial Communication: RS232, RS485, Modbus RTU/TCP & Communication Layers Explained
Understand PLC serial communication from the physical wire up — RS232 vs RS485, TX/RX data flow, Modbus RTU vs TCP framing, and the 7-layer OSI model mapped to industrial protocols.
🔌 The Physical Layer: Where Bits Become Voltage
Before any protocol runs, electricity must flow. This is where RS232 and RS485 live — they define how ones and zeros travel on copper wire.
🧠 Think of It Like a Road System
| Concept | RS232 | RS485 |
|---|---|---|
| Road type | Single-lane country road | Multi-lane highway |
| Distance | ~15 meters max | Up to 1200 meters |
| Passengers | 1 driver, 1 passenger (point-to-point) | Up to 32 devices on one bus |
| Speed vs distance | Fast but short | Fast AND long |
| Noise immunity | Low (single-ended) | High (differential signaling) |
📡 TX and RX: The Heartbeat of Serial Data
Every serial connection has two fundamental signals:
The Golden Rule of Wiring
Device A Device B
┌──────┐ ┌──────┐
│ TX ─┼──────────┼─ RX │
│ RX ─┼──────────┼─ TX │
│ GND ─┼──────────┼─ GND │
└──────┘ └──────┘TX always connects to RX (crossover)
Never TX-to-TX or RX-to-RX!
RS232 Signal Levels
Logic 1 (Mark): -3V to -15V
Logic 0 (Space): +3V to +15V +15V ┤ ┌───┐ ┌───┐
│ │ │ │ │ ← Logic 0
+3V ┤─ ─ ─│─ ─│─ ─ ─│─ ─│─ ─ ─
0V ┤ │ │ │ │
-3V ┤─ ─ ─│─ ─│─ ─ ─│─ ─│─ ─ ─
│ ────┘ └─────┘ └──── ← Logic 1
-15V ┤
RS485 Differential Signaling
┌─── Line A (D+) ───┐
Device ─────┤ ├───── Device
└─── Line B (D-) ───┘Logic 1: A > B (differential voltage > +200mV)
Logic 0: A < B (differential voltage < -200mV)
Noise hits BOTH lines equally → receiver subtracts it out!
This is why RS485 works over 1200m in noisy factories.
---
🏗️ RS232 vs RS485: Decision Matrix
| Feature | RS232 | RS485 |
|---|---|---|
| Signaling | Single-ended | Differential |
| Max cable length | 15m (50 ft) | 1200m (4000 ft) |
| Max devices | 2 (point-to-point) | 32 (multidrop bus) |
| Topology | Point-to-point | Bus / daisy-chain |
| Common use | PC-to-PLC debug, HMI | Fieldbus, sensor networks |
| Connector | DB9 / DB25 | Screw terminals (A, B, GND) |
| Typical baud rates | 9600–115200 | 9600–921600 |
| Industrial rating | Office/lab | Factory floor |
When to Use Each
RS232 → Use when:
✓ Short distance (< 15m)
✓ Only 2 devices talking
✓ Programming port / HMI connection
✓ Legacy equipmentRS485 → Use when:
✓ Long distance or noisy environment
✓ Multiple devices on one cable
✓ Modbus RTU network
✓ Industrial sensor bus
---
📦 Modbus: The Universal Industrial Language
Modbus is a protocol — it defines the meaning of the bytes sent over the wire. Think of RS232/RS485 as the postal truck, and Modbus as the letter format inside.
Modbus RTU vs Modbus TCP
| Feature | Modbus RTU | Modbus TCP |
|---|---|---|
| Transport | RS232 / RS485 serial | Ethernet (TCP/IP) |
| Framing | Binary with CRC-16 | TCP packet with MBAP header |
| Addressing | Station ID (1–247) | IP address + Unit ID |
| Speed | Up to 115200 baud | 10/100 Mbps Ethernet |
| Max devices | 247 per bus | Unlimited (network limit) |
| Error check | CRC-16 checksum | TCP built-in + optional |
| Cable | 2-wire (RS485) or 3-wire (RS232) | Cat5/Cat6 Ethernet |
Modbus RTU Frame Structure
┌──────────┬───────────┬──────────────┬──────────┐
│ Slave ID │ Function │ Data │ CRC-16 │
│ (1 byte) │ (1 byte) │ (N bytes) │ (2 bytes)│
└──────────┴───────────┴──────────────┴──────────┘
│ │ │ │
│ │ │ └─ Error detection
│ │ └─ Register addresses & values
│ └─ Read (03), Write Single (06), Write Multi (16)
└─ Which device responds (1–247)Frame gap: 3.5 character times of silence = end of frame
Modbus TCP Frame (MBAP Header)
┌──────────────┬────────────┬────────┬─────────┬───────────┬──────────┐
│ Transaction │ Protocol │ Length │ Unit ID │ Function │ Data │
│ ID (2 bytes) │ ID (2 bytes│(2 bytes│(1 byte) │ (1 byte) │(N bytes) │
│ │ = 0x0000) │ │ │ │ │
└──────────────┴────────────┴────────┴─────────┴───────────┴──────────┘
│
└─ Same as RTU slave ID
No CRC needed — TCP handles error detection!
Common Modbus Function Codes
| Code | Name | Description |
|---|---|---|
| 01 | Read Coils | Read digital outputs (ON/OFF) |
| 02 | Read Discrete Inputs | Read digital inputs |
| 03 | Read Holding Registers | Read analog/config values (most common) |
| 04 | Read Input Registers | Read analog input values |
| 05 | Write Single Coil | Set one digital output |
| 06 | Write Single Register | Set one register value |
| 15 | Write Multiple Coils | Set multiple digital outputs |
| 16 | Write Multiple Registers | Set multiple register values |
🌐 The 7-Layer OSI Model for Industrial Communication
The OSI model explains why we need different things like RS485 (physical) and Modbus (application). Each layer has a job:
Layer 7 │ APPLICATION │ Modbus commands, read/write registers
────────┤──────────────┤─────────────────────────────────────
Layer 6 │ PRESENTATION │ Data encoding (big-endian, ASCII vs RTU)
────────┤──────────────┤─────────────────────────────────────
Layer 5 │ SESSION │ Request/response pairing, timeouts
────────┤──────────────┤─────────────────────────────────────
Layer 4 │ TRANSPORT │ TCP (reliable) or UDP (fast)
────────┤──────────────┤─────────────────────────────────────
Layer 3 │ NETWORK │ IP addressing, routing between subnets
────────┤──────────────┤─────────────────────────────────────
Layer 2 │ DATA LINK │ Framing, MAC addresses, CRC checks
────────┤──────────────┤─────────────────────────────────────
Layer 1 │ PHYSICAL │ RS232/RS485 voltages, cables, connectors
Where Industrial Protocols Live
Protocol │ Layer 1 │ Layer 2-4 │ Layer 7
──────────────────┤──────────────┤──────────────────┤──────────────
Modbus RTU │ RS232/RS485 │ Serial framing │ Modbus
Modbus TCP │ Ethernet │ TCP/IP │ Modbus
EtherNet/IP │ Ethernet │ TCP/UDP + IP │ CIP
PROFINET │ Ethernet │ TCP/UDP + RT │ PROFINET IO
PROFIBUS DP │ RS485 │ Token passing │ PROFIBUS
EtherCAT │ Ethernet │ On-the-fly │ CoE/SoE
OPC UA │ Ethernet │ TCP/IP │ OPC UA Binary
---
💻 Structured Text: Modbus RTU Communication
PROGRAM ModbusRTUMaster
VAR
// Serial port configuration
SerialConfig : COM_CONFIG;
// Modbus request
mbRequest : MODBUS_REQUEST;
mbSend : BOOL := FALSE;
mbBusy : BOOL;
mbDone : BOOL;
mbError : BOOL;
// Data buffers
HoldingRegs : ARRAY[0..9] OF WORD; // Read from slave
WriteRegs : ARRAY[0..4] OF WORD; // Write to slave
// Communication state machine
CommState : INT := 0;
PollTimer : TON;
TimeoutTimer : TON;
RetryCount : INT := 0;
MAX_RETRIES : INT := 3;
END_VAR// ─── Serial Port Setup (done once) ───
SerialConfig.Port := 1; // COM1
SerialConfig.BaudRate := 19200; // Match slave setting
SerialConfig.DataBits := 8;
SerialConfig.StopBits := 1;
SerialConfig.Parity := 'E'; // Even parity (Modbus standard)
SerialConfig.Timeout := T#1S; // 1 second timeout
// ─── Communication State Machine ───
CASE CommState OF
0: // IDLE — Wait for poll interval
PollTimer(IN := TRUE, PT := T#500MS);
IF PollTimer.Q THEN
PollTimer(IN := FALSE);
CommState := 10;
END_IF;
10: // SEND READ REQUEST
mbRequest.SlaveID := 1; // Target device address
mbRequest.FunctionCode := 3; // Read Holding Registers
mbRequest.StartAddress := 40001; // First register
mbRequest.Quantity := 10; // Read 10 registers
mbSend := TRUE;
TimeoutTimer(IN := FALSE);
CommState := 20;
20: // WAIT FOR RESPONSE
TimeoutTimer(IN := TRUE, PT := T#2S);
IF mbDone THEN
// Success — copy data
HoldingRegs := mbRequest.ResponseData;
RetryCount := 0;
CommState := 30; // Next: write
ELSIF mbError OR TimeoutTimer.Q THEN
// Failed — retry logic
RetryCount := RetryCount + 1;
IF RetryCount >= MAX_RETRIES THEN
// Log alarm, skip to next cycle
RetryCount := 0;
CommState := 0;
ELSE
CommState := 10; // Retry
END_IF;
END_IF;
30: // SEND WRITE REQUEST
mbRequest.SlaveID := 1;
mbRequest.FunctionCode := 16; // Write Multiple Registers
mbRequest.StartAddress := 40101;
mbRequest.Quantity := 5;
mbRequest.WriteData := WriteRegs;
mbSend := TRUE;
CommState := 40;
40: // WAIT FOR WRITE CONFIRMATION
TimeoutTimer(IN := TRUE, PT := T#2S);
IF mbDone OR mbError OR TimeoutTimer.Q THEN
CommState := 0; // Back to idle
END_IF;
END_CASE;
---
🔧 Modbus TCP Client in Structured Text
PROGRAM ModbusTCPClient
VAR
// TCP connection
tcpConnect : TCP_CONNECT;
tcpConnected : BOOL;
ServerIP : STRING := '192.168.1.100';
ServerPort : UINT := 502; // Standard Modbus TCP port
// Modbus TCP transaction
TransactionID : UINT := 0;
mbTCPRequest : MODBUS_TCP_REQUEST;
// Read data from remote I/O module
RemoteInputs : ARRAY[0..15] OF WORD;
RemoteOutputs : ARRAY[0..7] OF WORD;
// Diagnostics
CommOK : BOOL;
ResponseTime : TIME;
RequestTimestamp : TIME;
PacketsSent : UDINT;
PacketsReceived : UDINT;
PacketsLost : UDINT;
END_VAR// ─── Build Modbus TCP Request ───
TransactionID := TransactionID + 1;
mbTCPRequest.TransactionID := TransactionID;
mbTCPRequest.ProtocolID := 0; // Always 0 for Modbus
mbTCPRequest.UnitID := 1; // Slave/unit identifier
mbTCPRequest.FunctionCode := 3; // Read Holding Registers
mbTCPRequest.StartAddress := 0;
mbTCPRequest.Quantity := 16;
// ─── Send and Track ───
IF tcpConnected THEN
RequestTimestamp := TIME();
// ... send mbTCPRequest over TCP socket ...
PacketsSent := PacketsSent + 1;
END_IF;
// ─── Response Handling ───
IF ResponseReceived THEN
ResponseTime := TIME() - RequestTimestamp;
PacketsReceived := PacketsReceived + 1;
CommOK := TRUE;
// Validate transaction ID matches
IF Response.TransactionID = TransactionID THEN
RemoteInputs := Response.Data;
END_IF;
ELSIF ResponseTimeout THEN
PacketsLost := PacketsLost + 1;
CommOK := FALSE;
END_IF;
---
🛡️ Common Communication Errors & Fixes
| Symptom | Likely Cause | Fix |
|---|---|---|
| No response at all | TX/RX wired wrong | Swap TX and RX wires |
| Garbled data | Baud rate mismatch | Match all devices to same baud |
| CRC errors | Parity mismatch | Set all devices to same parity (Even/None) |
| Intermittent timeout | Cable too long for RS232 | Switch to RS485 for >15m |
| Multiple slaves conflict | Same address on bus | Assign unique IDs 1–247 |
| Modbus TCP refused | Wrong port or firewall | Use port 502, check firewall rules |
| Data swapped (byte order) | Endianness mismatch | Check big-endian vs little-endian |
📊 Protocol Selection Flowchart
┌─────────────────┐
│ How far is the │
│ device? │
└────────┬────────┘
│
┌───── < 15m ──────┐──── > 15m ────┐
│ │ │
┌────▼────┐ ┌────▼────┐ ┌────▼────┐
│ RS232 │ │ RS485 │ │ Ethernet│
│ OK │ │ Modbus │ │ Modbus │
│ │ │ RTU │ │ TCP │
└─────────┘ └─────────┘ └─────────┘
│ │ │
1 device Up to 32 Unlimited
Debug/HMI Sensors/VFDs SCADA/MES
Summary
Serial communication is the nervous system of any PLC network. Understanding the difference between the physical layer (RS232/RS485 voltages and wiring) and the protocol layer (Modbus RTU/TCP commands) is essential for every automation engineer. RS232 is your quick debug cable; RS485 is your factory backbone; Modbus is the common language they all speak. Master these layers, and commissioning any industrial network becomes systematic rather than guesswork.