Overview
The Siemens SIMATIC S7-200 family of micro-PLCs does not implement Modbus in firmware as a built-in protocol. The CPU 224 — a 14-input / 10-output relay/transistor variant in the S7-200 line — exposes only the Siemens proprietary PPI (Point-to-Point Interface), Freeport (user-controlled ASCII/RS-485), and USS protocols on its Port 0. To use Modbus RTU on a CPU 224 you must load a Siemens-provided Modbus RTU slave (or master) instruction library into STEP 7 Micro/WIN and bind it to the Freeport-capable serial port. The library wraps the Modbus Application Data Unit (ADU) around the Freeport driver, performing CRC-16 generation, frame timing, and address mapping for you.
This guide covers the engineering decisions, the exact Micro/WIN library path, the wiring/cable choices for connecting a PC running a Modbus tester (such as the Modbus Tester Beta v0.3 referenced in field deployments) to a CPU 224, and the verification steps to confirm a working exchange. It also documents the master/slave role you must commit to before downloading the program: an S7-200 with the slave library can never spontaneously send a request, and the master library forces the CPU 224 to poll, not respond.
Modbus Protocol Fundamentals
Modbus is a master/slave (client/server) application-layer messaging protocol published by Modbus Organization in 1979. It is now an openly published, de-facto industrial standard carried over RS-232, RS-485, and TCP. Three PDU types are defined in the current Modbus specification:
- Modbus RTU – binary, 8-bit, CRC-16 error-checked. The only variant the S7-200 supports with its Micro/WIN library.
- Modbus ASCII – human-readable 7-bit hex with LRC. Not supported on the S7-200 Modbus library.
- Modbus TCP – uses port 502, MBAP header. Requires the S7-200 CP 243-1 Ethernet module, not the built-in PPI/Freeport port.
Per the Modbus Protocol reference and the Schneider Electric FAQ FA168406, a Modbus RTU frame on the wire is:
[ Silence ≥ 3.5 char ] [ SlaveAddress 1B ] [ FunctionCode 1B ] [ Data N bytes ] [ CRC16 2B (lo,hi) ] [ Silence ≥ 3.5 char ]
At 9600 bps with 11-bit characters (1 start, 8 data, even parity, 1 stop), a single 3.5-character silence is approximately 4.01 ms. This timing window is what separates one Modbus RTU frame from the next and is enforced by the S7-200 Freeport driver when the library is active. Violating inter-character timing will be reported by the S7-200 Modbus slave as error code 3 (see Error Codes below).
Only the master initiates transactions. A slave cannot spontaneously report an event. The four most common function codes used during bring-up testing are:
| FC | Name | Modbus Address Space | Typical S7-200 Mapping |
|---|---|---|---|
| 01 | Read Coils | 0xxxxx (bit) | Q0.0 – Q15.7 (digital outputs) |
| 02 | Read Discrete Inputs | 1xxxxx (bit) | I0.0 – I15.7 (digital inputs) |
| 03 | Read Holding Registers | 4xxxxx (16-bit word) | VW area starting at MBUS_INIT pointer |
| 04 | Read Input Registers | 3xxxxx (16-bit word) | AIW area (read-only words) |
| 05 | Write Single Coil | 0xxxxx (bit) | One Q bit |
| 06 | Write Single Register | 4xxxxx (16-bit word) | One VW |
| 15 (0F) | Write Multiple Coils | 0xxxxx (bit) | Contiguous Q bits |
| 16 (10) | Write Multiple Registers | 4xxxxx (16-bit word) | Contiguous VW |
S7-200 CPU 224 Hardware Reference
The CPU 224 (Siemens order number 6ES7 214-1AD23-0XB0 and successor 6ES7 214-1BD23-0XB0) is a 24 V DC powered micro-PLC with:
- 14 digital inputs, 10 digital outputs (relay or DC source, part-number dependent)
- Port 0: RS-485 half-duplex, optically isolated, supports PPI, Freeport, USS up to 38.4 kbps (firmware ≥ 1.21) and 187.5 kbps for MPI
- Port 1: RS-485, PPI/MPI/Freeport, up to 187.5 kbps
- 8/12 KB program memory, 8 KB data memory depending on firmware
- Battery-backed real-time clock
Port 0 is the conventional Modbus port because the original Modbus RTU library is anchored to it. The CPU 224's RS-485 port uses an 8-pin mini-DIN male connector (Siemens designation) on the front face. A second CPU 224, an S7-200 smart panel, or any RS-485 master can be wired in parallel; the line must be terminated with 120 Ω at both ends if the baud rate is ≥ 19.2 kbps and the cable length exceeds about 10 m.
Communication Cable and Wiring
The Softlink USB/PPI cable is a USB-to-RS-485 adapter designed for programming the S7-200. It exposes either an 8-pin mini-DIN (Siemens standard) or a DB-9 (D-sub) Siemens-style connector. Pin-out for the 8-pin mini-DIN is:
| Pin | Signal | Direction (PC ↔ PLC) |
|---|---|---|
| 1 | Shield | — |
| 2 | +24 V (logic power, optional) | — |
| 3 | RS-485 B (Data −) | Bidirectional |
| 4 | RTS (TTL level) | PC → PLC |
| 5 | +5 V (logic power) | — |
| 6 | +5 V return (GND) | — |
| 7 | +24 V return | — |
| 8 | RS-485 A (Data +) | Bidirectional |
For a one-to-one bench test with a PC running a Modbus tester, you need only pins 3, 6, and 8. If you daisy-chain a second device, install the 120 Ω terminator across pins 3 and 8 only at the two end nodes — never in the middle of a multi-drop trunk.
Error = 2 (CRC mismatch on the echoed request).Modbus Library for STEP 7 Micro/WIN
STEP 7 Micro/WIN V4.0 SP9 (the last release that targets the S7-200) ships with the Modbus RTU library on the installation media but does not load it by default. The library contains the following subroutines:
| Subroutine | Role | Notes |
|---|---|---|
| MBUS_CTRL | Port 0 initialization | Mode, baud, parity, timeout. Must be called once per scan for slave, once per cycle for master. |
| MBUS_INIT | Allocate V-memory data block | Pointer to holding-register area, I/O offsets, slave address, response timeout. |
| MBUS_SLAVE | Modbus RTU slave engine | Called every scan; processes one outstanding request per call. |
| MBUS_MSG | Modbus RTU master send/read | Read/write single or multiple, FC 01–06, 15, 16. |
To install:
- Launch Micro/WIN, open the project for the CPU 224.
- Menu: Tools → Instruction Libraries (or the legacy Component Catalog → Libraries tree).
- Click Add, browse to
\Step7\Microwin\Lib\Modbus\Modbus_RTU_Slave.mwlfor the slave variant, orModbus_RTU_Master.mwlfor the master variant. - The library becomes available under the Call Subroutine node; its symbols appear in the local symbol table.
The library itself is provided by Siemens and does not carry a runtime licence key on the S7-200 (the protection is on the Micro/WIN PC installation). However, redistribution of compiled blocks that include the library is governed by the Micro/WIN End-User Licence Agreement; verify with Siemens if the application will be replicated across multiple machines.
Prerequisites
Before the bench test, confirm the following:
- STEP 7 Micro/WIN V4.0 SP9 installed on a Windows PC (Siemens no longer ships Micro/WIN; existing installations are still supported under the SIMATIC S7-200 product lifecycle).
- S7-200 CPU 224 powered with 24 V DC, in STOP for download, with a known-good program or an empty OB1.
- Softlink USB/PPI cable with the correct Windows USB-serial driver (CH340 or FTDI, model dependent). The virtual COM port number should be ≤ 9 to avoid legacy COM-port limits in Micro/WIN.
- Modbus tester on the PC. For a one-shot bench test, a free tool such as Modbus Poll (modbuspoll.com), QModMaster, or the standalone Modbus Tester Beta v0.3 used in the original field deployment is sufficient.
- Two 120 Ω terminators if the cable run exceeds 10 m at 19.2 kbps or higher.
- Common ground reference between PC (through the cable shield) and PLC 24 V common.
Configuration A — S7-200 as Modbus RTU Slave
This is the most common bring-up test. The PC running the Modbus tester is the master; the CPU 224 is the slave. Place the following ladder in OB1:
// --- First-scan initialization (SM0.1 = 1 on first cycle) ---
NETWORK 1
SM0.1 MBUS_CTRL_RUN // Always enabled, watchdog bit
// EN Mode=1 (slave), Baud=9600, Parity=2 (Even), Timeout=1000 ms
// ENO Done, Error
NETWORK 2
SM0.1 MBUS_INIT_RUN
// EN Slave=1, HoldStart=&VW100, MaxQ=8, MaxAI=8,
// MaxHold=100, MaxIn=0
// --- Every scan (SM0.0 = 1) ---
NETWORK 3
SM0.0 MBUS_SLAVE_RUN
// EN Done, Error, Slave_ID_returned, Function_returned
Parameter values to enter on the MBUS_INIT instruction box (Micro/WIN pops a dialog):
| Parameter | Value | Meaning |
|---|---|---|
| Slave | 1 | Modbus slave address; the master must poll address 1 |
| HoldStart | &VW100 | Pointer to first holding register (Modbus 400101 ↔ VW100) |
| MaxQ | 0 – 32 | Number of Q bits exposed (0xxxxx) |
| MaxAI | 0 – 32 | Number of AIW words exposed (3xxxxx) |
| MaxHold | 1 – 100 | Number of VW words exposed (4xxxxx) |
| MaxIn | 0 | Discrete inputs (1xxxxx) – not used in bench test |
On the Modbus tester set: Connection = Serial RTU, COMx, 9600, 8, E, 1, Slave ID 1, Timeout 1000 ms, Poll Rate 1000 ms. Issue a function code 03 read from holding register 400101. The first poll should return the current value of VW100. If you see Illegal Data Address (exception 02) the HoldStart pointer or MaxHold is wrong; if you see Illegal Function (01) the CPU 224 may still be in PPI mode — toggle Port 0 to Freeport by ensuring MBUS_CTRL is in the scan.
Configuration B — S7-200 as Modbus RTU Master
To make the CPU 224 the master (e.g., to poll a third-party VFD or a remote I/O block) you switch to the master library and call MBUS_MSG:
// One-shot init on first scan
NETWORK 1
SM0.1 MBUS_CTRL_RUN
// EN Mode=0 (master), Baud=19200, Parity=2, Timeout=1000 ms
// Trigger one poll per second from a 1-Hz clock bit (SM0.5 = 1 s toggle)
NETWORK 2
SM0.5 MBUS_MSG_RUN
// EN Done, Error, Slave=2, RW=0 (read),
// Addr=40001, Count=1, DataPtr=&VW200
The Done output must be monitored; a new MBUS_MSG cannot be initiated while Done = 0, otherwise the library returns Error = 6 (bus busy). A common ladder idiom is:
NETWORK 3
MBUS_MSG.Done ----( S ) M0.0 // M0.0 = 1 once previous call is complete
SM0.5 ----( R ) M0.0 // clear at next 1-Hz tick so a fresh call can start
Wiring the Bench Test
- Connect the Softlink USB/PPI cable to Port 0 of the CPU 224. The connector is keyed; do not force.
- Plug the USB end into the PC; allow the driver to enumerate the virtual COM port (Device Manager → Ports).
- Open the Modbus tester and pick the COM port number. Set 9600, 8, E, 1 to match
MBUS_CTRL. - Power the CPU 224. Place the CPU in RUN. The library now owns Port 0; Micro/WIN can no longer program over that port until the library is removed or Port 0 is reinitialised via the System Block.
- If you also need to program, move the cable to Port 1 of the CPU 224 for the next download, or temporarily comment out
MBUS_CTRLand re-download with the cable in PPI mode.
Verification Procedure
- From the Modbus tester, write a known value (e.g., 12345 decimal = 0x3039) to holding register 400101.
- Read the same register back. Confirm the value returned matches.
- In Micro/WIN, open Status Chart, add
VW100in HEX and DEC. Confirm the same value appears. - Toggle a Q bit (e.g., Q0.0) using FC 05 force-single-coil. Verify the LED on the CPU 224 module illuminates and the Status Chart shows Q0.0 = 1.
- Force a Modbus error by sending a request to slave ID 2 (does not exist). Expect the tester to report No Response (timeout), and the
MBUS_SLAVEError output to remain 0 because the frame was ignored, not corrupted.
Error Codes Returned by MBUS_SLAVE / MBUS_MSG
| Code | Meaning (per S7-200 System Manual) | Likely Field Cause |
|---|---|---|
| 0 | No error | — |
| 1 | Parity / framing error | Baud rate or parity mismatch with the master |
| 2 | CRC-16 mismatch | Noise on the RS-485 cable, wrong terminator, or echo from PC adapter |
| 3 | Inter-character timeout / illegal function | Master between-frame delay too short, or unsupported FC |
| 4 | Memory pointer out of range | HoldStart + MaxHold exceeds V-memory |
| 5 | PLC address out of range | MaxQ/MaxAI/ MaxIn set higher than the CPU's I/O count |
| 6 | Master: previous MBUS_MSG still active | Back-to-back call without checking Done |
| 7 | Master: response timeout | Slave offline, wrong address, A/B polarity reversed |
Troubleshooting Matrix
| Symptom | First Check | Second Check | Resolution |
|---|---|---|---|
| Tester: no response, all polls | Port 0 LED activity on CPU 224 | RS-485 A/B polarity at cable | Swap pins 3 and 8; the Softlink cable label is not polarity-agnostic |
| Tester: CRC error or exception 03 | Baud / parity / stop bits | Cable length vs. termination | Match 9600/8/E/1 on both sides; install 120 Ω at both ends |
| S7-200 returns correct values in tester but does not act on Q writes | Force bit is gated by logic in OB1 | CPU in STOP | Add unconditional MOVE / SET, or check SM0.7 / mode switch |
| Library block missing from Micro/WIN | Tools → Instruction Libraries | Modbus_RTU_Slave.mwl present in install path | Re-install Micro/WIN; the library ships in the same installer |
| Program downloads successfully, but MBUS_SLAVE Error = 1 immediately | Verify MBUS_CTRL EN is true every scan | Verify Mode parameter = 1 (slave) | Use a contact in series; the instruction must be called each cycle |
| Tester times out only at 38.4 kbps | CPU firmware version | Some early CPU 224 FW 1.20 do not support 38.4 k Freeport | Drop to 19.2 k or upgrade firmware; verify in the S7-200 System Manual |
Best Practices for Field Deployment
-
Bind the library to a single port: never call both
MBUS_SLAVEand a Freeport XMT/RCV on the same port. Micro/WIN programming via the same port is also blocked while the library is in RUN. - Reserve V-memory for the library: a 300-byte block starting at the HoldStart pointer is the rule of thumb; collisions with the project variables produce hard-to-diagnose 0x000A scan errors.
- Use even parity unless the master is fixed at no parity. The CRC-16 is identical, but even parity catches single-bit electrical faults that a CRC alone may not catch on a 16-byte register read.
- Limit poll rate to ≤ 50 ms per slave: the S7-200 can sustain heavier traffic, but bench testing at 50 ms reveals intermittent noise problems that are hidden by a 1000 ms poll.
- Document the V-memory map in the project: at commissioning, export a CSV from the Symbol Table with column Modbus Address next to Symbol. This avoids the all-too-common phone call that begins "What is 400127?"
References to Official Documentation
- Modbus Organization — protocol specification and current revision: modbus.org
- National Instruments — Modbus protocol in-depth: ni.com Modbus reference
- Modbus Tools — frame structure and timing: modbustools.com
- Schneider Electric FAQ FA168406 — Modbus installation principles: se.com FAQ FA168406
- Wikipedia — Modbus (cross-reference for function codes and PDU/ADU framing): Wikipedia: Modbus
Where do I find the Modbus RTU library inside STEP 7 Micro/WIN?
It is not loaded by default. Open Tools → Instruction Libraries, click Add, and browse to the \Step7\Microwin\Lib\Modbus\ directory. The slave library file is Modbus_RTU_Slave.mwl and the master library is Modbus_RTU_Master.mwl. Once added, the subroutines MBUS_CTRL, MBUS_INIT, MBUS_SLAVE (or MBUS_MSG) appear under Call Subroutine in the navigation tree.
Can the S7-200 CPU 224 be both a Modbus master and a Modbus slave at the same time?
No, not on the same port. The library binds the chosen role to Port 0 (slave) or to a master polling loop. To do both, you must use Port 0 as slave and Port 1 with a second MBUS_CTRL / MBUS_MSG pair in master mode, or use the S7-200 as slave on Port 0 and run a third-party master elsewhere on the same trunk.
Why does my Modbus tester report no response even though the S7-200 program downloaded without errors?
The most common causes are: (1) RS-485 A/B polarity reversed (swap pins 3 and 8 of the mini-DIN), (2) baud or parity mismatch between MBUS_CTRL and the tester (set both to 9600, 8, E, 1 for first try), (3) terminator missing on a long cable, or (4) the program is loaded but the CPU is still in STOP — toggle the mode switch to RUN so MBUS_SLAVE executes each scan.
What is the difference between the Softlink USB/PPI cable and a generic USB-to-RS-485 adapter?
The Softlink cable is wired for Siemens PPI pin-out (mini-DIN 8) and contains internal bias resistors and, on most models, echo-suppression suitable for PPI programming. It will work for Modbus RTU at 9.6/19.2 kbps on a short bench cable, but on long plant runs prefer a generic RS-485 adapter (e.g., FTDI USB-RS485-WE) wired to pins 3 and 8 only, with a 120 Ω terminator at each end. The Softlink cable also installs a virtual COM port that Micro/WIN expects to be COM1–COM9.
Which holding register does the S7-200 expose first and how is it addressed?
The MBUS_INIT instruction's HoldStart parameter is a V-memory pointer. If you set HoldStart = &VW100, then Modbus address 400101 maps to VW100, 400102 to VW102, and so on. The offset 400100 is always subtracted by the library because Modbus holding registers are 1-based while S7-200 V-words are byte-addressed in pairs.
Does the Modbus library need a paid licence to run on the CPU 224?
The Modbus RTU slave and master libraries ship with Micro/WIN V4.0 SP9 and do not require a runtime licence key on the S7-200 CPU. The licence terms that govern the Micro/WIN development environment on the engineering PC still apply, and redistribution of the compiled blocks is governed by the Micro/WIN End-User Licence Agreement — verify with Siemens if you are replicating the application across multiple machines.