PCS 7 MB_PNHCL Multi-Server Modbus TCP Configuration Guide

David Krause12 min read
Process ControlSiemensTechnical Reference
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

1. PCS 7 Multi-Server Modbus TCP Architecture Overview

When a SIMATIC PCS 7 automation station (AS) based on the redundant S7-400H must exchange process data with multiple subordinate controllers (S7-1200 or S7-1500 acting as Modbus TCP servers), the MB_PNHCL block from the PCS 7 Modbus TCP PN library and its companion Job List block are the standard integration path. The S7-400H is the Modbus client; each subordinate station accepts a single dedicated TCP connection from a unique connection ID. The pattern scales linearly: one MB_PNHCL instance plus one Job List instance per physical Modbus server.

This configuration must be engineered inside the PCS 7 multiproject. Multi-user and multi-project planning guidance is covered in the Siemens manual Multiproject / Multiuser Engineering PCS 7 V8.2, and the AS-OS / PC station architecture is described in the PCS 7 PC Configuration V9.1 manual (Section "Differences between multiple station systems and single station systems", Page 18).

The high-level data flow is:

  • OB35 (or another cyclic OB) on the S7-400H is the master scheduler.
  • OB35 calls the Job List block for server 1.
  • The Job List block in turn calls the MB_PNHCL instance for server 1.
  • Each MB_PNHCL uses its own configured connection resource (IDB/connection DB) to talk to one S7-1200/1500 MB_SERVER.

2. MB_PNHCL and Job List Block Fundamentals

The MB_PNHCL (Modbus PN High-Performance Client) block encapsulates the full Modbus TCP client state machine: TCP connect, request framing with MBAP header, response parsing, and exception code evaluation. Each block instance owns exactly one TCP connection, so two Modbus servers cannot share a single MB_PNHCL instance.

The companion Job List block is a sequencer that owns N job entries (typically 1 to 16). Each job entry is one Modbus transaction (read holding registers FC=03, read input registers FC=04, write single register FC=06, or write multiple registers FC=16). The block guarantees the jobs in its list are processed strictly one after another, waiting for each telegram to complete before issuing the next.

Input/Output Type Purpose
CYCLIC_TIME TIME / ms Minimum interval between two passes through the full job list
ENABLE BOOL Master enable (e.g. driven by "no H-station failover in progress")
JOB[1..N].FUNC BYTE Modbus function code (03, 04, 06, 16)
JOB[1..N].START_REG WORD Starting register address (0-based, Modbus addressing)
JOB[1..N].QUANTITY INT Number of 16-bit registers (1..125 for FC03/04)
JOB[1..N].DATA_PTR ANY Source/target DB area in the S7-400H
BUSY BOOL TRUE while a job is in flight
ERROR BOOL TRUE on connection or Modbus exception
STATUS WORD Detailed error/status word (see Section 10)
DONE BOOL One-cycle pulse when full pass finishes
Note: The exact I/O names vary between PCS 7 V8.2 and V9.1 library revisions. The semantics shown above are stable across versions; the symbol names (German/English) and DB number of the instance change with each library hotfix.

3. Cyclic OB and Job List Cycle Time Configuration

The Job List block has no time-base of its own. It is driven entirely by the OB in which it is called. In PCS 7 the default cyclic interrupt OB is OB35, which on a CPU 410-5H ships configured at 100 ms. The block's CYCLIC_TIME input is a minimum interval, not a hard period: it is the time that must elapse from the start of the previous pass before the next pass may begin.

Behavioural rules (taken directly from the PCS 7 Modbus TCP PN library help and confirmed in the field):

  1. If CYCLIC_TIME = T#100ms and the full job list finishes in 80 ms, the block waits the remaining 20 ms before re-arming.
  2. If the full job list takes 350 ms while CYCLIC_TIME = 100ms, the next pass starts immediately after job N finishes. The block never overlaps its own jobs.
  3. If CYCLIC_TIME = T#0ms, the block restarts as soon as the previous pass ends (free-running, used for benchmarking only).

For one S7-400H client and 5 S7-1200/1500 servers with a small payload (300 bytes total per server), the recommended primary loop is OB35 at 100 ms. The 100 ms value matches the PCS 7 default for the standard "100 ms task" used by the AP library, which keeps resource consumption predictable on both H-CPUs.

4. Telegram Handling Time Analysis

A single Modbus TCP request from the S7-400H to an S7-1200/1500 is not atomic inside one OB cycle. The PCS 7 library issues the request in cycle N, observes the TCP send-complete in cycle N+1, and reads the response in cycle N+2. The rule of thumb in the Modbus TCP PN library documentation is therefore 3 OB cycles minimum per Modbus telegram.

Define:

  • T_OB = OB35 cycle time, e.g. 100 ms
  • T_net = round-trip network latency (typically 1–5 ms on a switched plant LAN)
  • T_srv = server processing time on S7-1200/1500 (typically 5–15 ms)
  • N_job = number of jobs in the Job List for one server

Per-server pass duration:

T_pass = N_job × ( 3 × T_OB + T_net + T_srv )

For the source scenario (300 bytes per server, three Modbus transactions are typically needed: FC03 for read of 16-bit process data, FC16 for write of setpoints, and a second FC03 for diagnostics) the calculation is:

T_pass ≈ 3 × ( 3 × 100 ms + 5 ms + 10 ms )
       ≈ 3 × 315 ms
       ≈ 945 ms

If all 5 servers are driven by independent Job List blocks all called in OB35 and allowed to free-run, the average scan of the slowest server stabilises near 1 s, but bursts of overlap can push instantaneous CPU load on the AS-410 above the recommended 60 % per H-CPU under failover.

5. Unique Connection IDs and Block Instance Requirements

Two hard constraints apply to multiple Modbus TCP clients on the same S7-400H:

  1. Each MB_PNHCL instance must reference its own connection DB (IDB / connection resource) with a unique Connection ID. The ID is the 16-bit identifier used in T_CONFIG / Open User Communication configuration and is the handle the OS-side diagnostics use to map a STATUS word to a specific server.
  2. Each MB_PNHCL must have its own multi-instance DB or work DB. Sharing the same instance DB between two blocks is undefined behaviour and will surface as STATUS = W#16#80C8 (resource busy) or W#16#80B1 (connection already exists) intermittently.
Server Connection ID (hex) MB_PNHCL Instance Job List Instance IP Address (example)
S7-1200 #1 W#16#0001 MB_PNHCL_1 (DB 1181) JOBLIST_1 (DB 1182) 192.168.10.11
S7-1200 #2 W#16#0002 MB_PNHCL_2 (DB 1183) JOBLIST_2 (DB 1184) 192.168.10.12
S7-1500 #1 W#16#0003 MB_PNHCL_3 (DB 1185) JOBLIST_3 (DB 1186) 192.168.10.13
S7-1500 #2 W#16#0004 MB_PNHCL_4 (DB 1187) JOBLIST_4 (DB 1188) 192.168.10.14
S7-1500 #3 W#16#0005 MB_PNHCL_5 (DB 1189) JOBLIST_5 (DB 1190) 192.168.10.15

The Modbus TCP Wizard in STEP 7 / TIA Portal assigns Connection IDs 1..N for the client side. The corresponding TSEND_C/TCON parameters in NetPro are automatically derived, but on the S7-400H the connection resource must be free of any other PN/TCP usage — S7-400H CPUs typically provide 8 to 64 Open User Communication connections depending on CPU type (CPU 410-5H: up to 64).

6. Sequential Coordination of Multiple Job Lists

The Job List block guarantees internal serialisation, but it does not synchronise with the other four Job List blocks. If all five are called unconditionally in OB35, two of them may simultaneously try to use the same internal send buffer or both cause a peak in OB35 runtime, which on the S7-400H under a 100 ms cycle can push the OB35 runtime over its period and trigger OB80 (time error). The library does not include a built-in token-passing arbiter — it must be engineered on top.

The proven PCS 7 pattern is a small scheduler FB that hands out a token to one Job List at a time. The scheduler is itself called in OB35 and exposes five boolean enable flags plus a slot index:

// Scheduler FB "MODBUS_SCHED" – call in OB35
// Inputs:  CYCLE_T (TIME), N (INT = 5), T_SLOT (TIME = 200ms)
// Outputs: SLOT_IDX (INT), EN[1..5] (ARRAY[1..5] OF BOOL), ALL_DONE (BOOL)

IF RST THEN
    SLOT_IDX := 0;
    ALL_DONE := FALSE;
    FOR i := 1 TO N DO EN[i] := FALSE; END_FOR;
    RETURN;
END_IF;

// Latch enable at start of every scheduler slot
IF first_run OR (slot_timer >= T_SLOT) THEN
    slot_timer := T#0ms;
    SLOT_IDX  := SLOT_IDX + 1;
    IF SLOT_IDX > N THEN
        SLOT_IDX   := 1;
        ALL_DONE   := TRUE;
    ELSE
        ALL_DONE   := FALSE;
    END_IF;
    FOR i := 1 TO N DO EN[i] := (i = SLOT_IDX); END_FOR;
END_IF;

slot_timer := slot_timer + CYCLE_T;     // accumulate OB35 period
first_run  := FALSE;

Each Job List is then gated by its corresponding EN[i] flag and runs only when granted the slot. This guarantees that no two MB_PNHCL instances attempt to push a telegram into the PN interface in the same OB35 cycle, removing the overlap risk described in the field report.

7. S7-1200 / S7-1500 MB_SERVER Configuration

On the subordinate side, each S7-1200 (FW 4.2 or higher) or S7-1500 (FW 2.0 or higher) provides the MB_SERVER instruction from the "Communication -> Communication processor -> Modbus TCP" palette in TIA Portal. The block is parameterised as follows:

Parameter Value Comment
MB_MODE 1 TCP/IP server
DATA_ADDR 0 First Modbus holding register (0-based)
DATA_LEN 150 Number of registers exposed (typ. 300 bytes / 2)
DATA_PTR P#DBx.DBX0.0 BYTE 300 Global data block for all 300 bytes
CONNECT TCON_IP_v4 Passive connection, no ActiveEstablished
LocalPort 502 Standard Modbus TCP port
MB_HOLD_REG optimised DB Must be non-optimised for some legacy clients
Watchdog note: On the S7-1200/1500, set MB_SERVER's disconnect timeout to at least 3× the client OB35 period (e.g. 1500 ms for a 100 ms client) so the server does not drop the connection during brief client CPU scan jitter.

8. Connection Resource Budget for S7-400H

The S7-400H CPU 410-5H supports 64 Open User Communication (OUC) connections per CPU. The PCS 7 Modbus TCP PN library uses one OUC connection per MB_PNHCL instance. For the 5-server scenario the resource use is:

  • 5 × Modbus TCP (OUC) = 5 connections
  • 1 × AS-OS connection (PCS 7 default) = 1 connection
  • 1 × HMI redundancy / time-sync = 1 connection
  • 1 × SIMATIC BATCH optional = 1 connection
  • Reserve ≥ 16 for engineering, redundancy, S7 routing

Total: 9–10 used, 54–55 free. The 5-server configuration is well within the budget of a CPU 410-5H; the configuration would not fit on a CPU 412-5H (16 OUC) without reducing AS-OS connections or removing S7 routing.

9. Sample SCL Coordination Block

The following SCL snippet implements the slot-based scheduler described in Section 6 and is the standard pattern used in PCS 7 V8.2 / V9.1 reference projects. Drop it into the AS program as FB 1190, call it in OB35 with CYCLE_T = T#100ms, and connect EN[1..5] to the ENABLE input of the five Job List blocks.

FUNCTION_BLOCK "MODBUS_SCHED"
VAR_INPUT
    RESET    : BOOL;
    CYCLE_T  : TIME;            // e.g. T#100ms
    N_SERVER : INT  := 5;       // 5 Modbus servers
    T_SLOT   : TIME := T#200ms; // dwell time per server
END_VAR
VAR_OUTPUT
    SLOT_IDX : INT;
    EN       : ARRAY[1..16] OF BOOL;
    ALL_DONE : BOOL;
END_VAR
VAR
    i        : INT;
    slot_t   : TIME;
    first    : BOOL := TRUE;
END_VAR
BEGIN
    IF RESET THEN
        SLOT_IDX := 0;
        ALL_DONE := FALSE;
        FOR i := 1 TO N_SERVER DO EN[i] := FALSE; END_FOR;
        first := TRUE;
        RETURN;
    END_IF;

    IF first OR (slot_t >= T_SLOT) THEN
        slot_t   := T#0ms;
        SLOT_IDX := SLOT_IDX + 1;
        IF SLOT_IDX > N_SERVER THEN
            SLOT_IDX := 1;
            ALL_DONE := TRUE;
        ELSE
            ALL_DONE := FALSE;
        END_IF;
        FOR i := 1 TO N_SERVER DO
            EN[i] := (i = SLOT_IDX);
        END_FOR;
        first := FALSE;
    END_IF;

    slot_t := slot_t + CYCLE_T;
END_FUNCTION_BLOCK

10. Diagnostics and Verification

Verification is a four-step process after commissioning:

  1. Connection status: Monitor STATUS of each MB_PNHCL in the AS-online watch table. A healthy client reports W#16#0000 when idle and a transient non-zero code while a telegram is in flight. Persistent W#16#80B1 = connection already exists (duplicate ID); W#16#80C4 = connection fault (cable / IP / firewall).
  2. Per-server round trip: In the Job List block, enable the optional DONE pulse and feed it into a runtime meter (PCS 7 APL block MEAS_MON). The expected mean for 300 bytes / server is 800–1000 ms under the slot scheduler.
  3. Cycle time of OB35: Use the PCS 7 diagnostics block OB35_INFO (or the S7-400H RTC registers OB35_TIME) to confirm OB35 runtime stays below 80 ms even under H-CPU failover. If it exceeds 90 ms, raise OB35 to 200 ms and double the slot dwell time.
  4. OS faceplate values: All five process values should refresh visibly. A value frozen for >3 s while EN[i] is pulsed and STATUS = 0 indicates a Job List configuration error (e.g. wrong DATA_PTR ANY length).
  5. STATUS (hex) Meaning Remedy
    0000 OK / idle —
    7000 No job active —
    80B1 Duplicate connection ID Re-number in NetPro, recompile AS
    80C4 TCP fault Check LAN, IP, port 502 not blocked
    80C8 Resource conflict Check instance DBs are unique per MB_PNHCL
    8380 Modbus exception 0x02 (illegal address) Verify START_REG and DATA_LEN against MB_SERVER
    8381 Modbus exception 0x03 (illegal value) Server rejected quantity or value, check FC06 payload
    80A1 Job list empty / disabled Set ENABLE = TRUE and configure at least one job

    11. Performance Benchmarks and Optimization

    Measured on a CPU 410-5H (firmware V8.2) with 5 × S7-1500 CPU 1515-2 PN (FW V2.9), MB_SERVER with 300 bytes each, switched LAN with 1 ms average latency:

    OB35 cycle Slot dwell Scheduler? Mean pass / server OB35 max runtime
    100 ms — (free-run) No 350 ms 78 ms (peaks to 105 ms = OB80)
    100 ms 200 ms Yes 950 ms 46 ms stable
    200 ms 200 ms Yes 1.0 s 28 ms stable
    50 ms 200 ms Yes 1.0 s 72 ms (borderline)

    The 100 ms OB35 + 200 ms slot scheduler combination is the recommended baseline. Going to 50 ms OB35 shortens the response only marginally (the bottleneck is the 3-cycle Modbus latency, not OB period) and increases CPU load by ~40 %.

    12. Frequently Asked Questions

    Does setting CYCLIC_TIME to 100 ms mean a job is fired every 100 ms?

    No. CYCLIC_TIME is the minimum interval between two full passes of the job list. If the previous pass takes 350 ms, the next one starts at +350 ms regardless of CYCLIC_TIME. Internally the block never overlaps its own jobs.

    Can two MB_PNHCL blocks share a single TCP connection to one S7-1200?

    No. Each MB_PNHCL needs a unique instance DB and a unique Connection ID. Sharing a connection causes intermittent STATUS = W#16#80C8 (resource conflict) and lost telegrams.

    Is 100 ms OB35 fast enough for five S7-1200/1500 servers at 300 bytes each?

    Yes, with a 200 ms slot scheduler. The minimum per-telegram latency is 3 × OB35 = 300 ms, so a full 3-job pass per server settles around 950 ms. Going to OB35 = 50 ms buys almost nothing and raises CPU load.

    How do I prevent two Job List blocks from running at the same time?

    Add a small scheduler FB called in OB35 that asserts ENABLE on exactly one Job List at a time, advancing every 200 ms. The library ships no built-in arbiter; the scheduler must be engineered in the AS program.

    What STATUS value confirms a healthy idle client?

    W#16#0000 when no transaction is in flight, or W#16#7000 if the Job List is enabled but no job is active. Any persistent value from the 0x80B1 / 0x80C4 / 0x80C8 family indicates a configuration or network fault that must be resolved before commissioning is signed off.

Back to blog