S7-1200 PUT/GET Communication Troubleshooting in TIA Portal

David Krause15 min read
S7-1200SiemensTroubleshooting
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

S7-1200 PUT/GET Communication Troubleshooting in TIA Portal

The PUT and GET instructions implement S7 communication between two S7-1200 CPUs (or between an S7-1200 and an S7-300/400/1500 partner) over the integrated PROFINET interface. A correctly configured pair transfers data blocks, bit memory, and process image between the local CPU and a remote partner CPU. When the call returns ERROR = 1, the bus status remains STATUS = 0, or the partner CPU never acknowledges, the failure is almost always caused by one of four configuration gaps: a disabled remote-access property on the partner CPU, a non-standard block access type, mismatched area definitions, or an unsupported data type mapping at the source.

This reference applies to S7-1200 CPUs (firmware V1.x through V4.x) configured in TIA Portal V11 SP2 through V17. The S7-1214 AC/DC/RLY used as the test target is functionally identical to other S7-1200 variants for PUT/GET purposes. It is not a hardware problem; the integrated PROFINET port of the S7-1214 supports S7 communication natively without an additional CP module.

Problem Overview

The reported symptom chain is consistent across the field:

  • A PUT or GET block is inserted in PLC 1 (the local CPU), and the connection resource is configured with the partner IP address of PLC 2.
  • The block compiles cleanly, downloads, and runs, but the partner CPU does not return the requested data.
  • Inspecting the PUT block instance data block shows REQ toggling, but DONE never sets, ERROR stays low, and the value at the source address never appears at the destination.
  • On PLC 2, a tag exists in a global data block (or as a local static in an FB) but the tag is not visible to PLC 1 because the block access attribute is set to optimized or the tag has no symbolic address exposed to S7 communication.

The PLC 2 tag is also declared as BOOL, but the PLC 1 PUT block source area expects a WORD. Without a matching WORD destination, the PUT call cannot transfer a single bit cleanly across the S7 link; it requires an area of at least one byte (BYTE/WORD/DWORD).

Engineering rule: The PUT and GET instructions exchange raw byte-aligned memory areas. BOOL is not a valid ADDR_i or SD_i data type. Map any single bit to a BOOL tag inside a DB and read or write a full BYTE/WORD that contains that bit. Do not pass %I0.0 or %M0.0 directly to PUT/GET.

Root Cause Analysis: Four Configuration Gaps

The S7-1200 PUT/GET communication handshake fails for one of four mutually exclusive reasons. Diagnose in this order because the symptoms overlap.

# Configuration Gap Symptom on the Block Where to Look
1 Remote-access property disabled on partner CPU ERROR = 1, STATUS = 0x0001 (System error in the partner CPU) Devices & Networks → Partner CPU → Properties → Protection → Permit access with PUT/GET communication from remote partner
2 Data block optimized (non-standard access) ERROR = 1, STATUS = 0x000F (Address of the data block invalid) DB properties → Attributes → Block access: Standard (not Optimized)
3 ADDR_i length > RD_i / SD_i length ERROR = 1, STATUS = 0x000E (Insufficient space in the target area) PUT/GET block instance → ID, ADDR_i, SD_i, RD_i parameters
4 Type mismatch: BOOL at source, WORD at destination Compile error or runtime silent failure with no data written Use AT view on a WORD, or declare a BOOL tag inside a standard DB

For a S7-1200 firmware V1.x target, only standard (non-optimized) data blocks participate in S7 PUT/GET communication. The optimized block access introduced with firmware V4.0 is fully supported on S7-1200 V4.x and S7-1500, but it is not available on the older V1.x/2.x/3.x firmware common on field-deployed 1214 CPUs. The block must be created with Access: Standard from the DB properties dialog. Right-click the DB in the project tree, choose Properties, and confirm that Optimized block access is unchecked.

Prerequisites

Confirm each item below before opening the PUT or GET block editor. Skipping the first two items is the single most common cause of the no-data symptom.

  1. Hardware: Two S7-1200 CPUs with PROFINET interface (e.g. 6ES7214-1BE30-0XB0, 6ES7214-1AG40-0XB0). Direct Ethernet crossover or through a switch on the same subnet.
  2. IP addressing: PLC 1 in subnet 192.168.0.1/24, PLC 2 in subnet 192.168.0.2/24 (or any RFC 1918 private address on the same /24). Subnet mask must match on both controllers.
  3. Firmware: V2.0 or higher on both CPUs. Firmware V1.0 is restricted to one S7 connection per CPU; PUT/GET share a single connection with other S7 functions and may be saturated by HMI traffic.
  4. TIA Portal: V11 SP2 Update 5 minimum, V13 SP1 or V15.1 recommended for newer firmware. The TIA Portal major version must be at least the firmware-major version of the CPU (TIA V13 cannot download to firmware V4.4 without update).
  5. Project configuration: Both PLCs are inserted in the same TIA project under Devices & Networks. The Devices & Networks editor is used to define the S7 connection resource; the PUT/GET block can only resolve a connection that already exists in the project.

Solution 1: Enable Remote Partner Access on the Partner CPU

The Protection property on the S7-1200 CPU defaults to No access for PUT/GET from remote partners. The PUT block on PLC 1 cannot read or write PLC 2 memory until the operator explicitly opens the access path.

  1. In the TIA project tree, right-click PLC_2 and open Properties.
  2. Select the Protection entry on the left side of the Properties dialog.
  3. Scroll to Permit access with PUT/GET communication from remote partner (PLC, HMI, OPC, …) and tick the checkbox.
  4. Click OK to apply.
  5. Re-download the hardware configuration to PLC 2 (a Stop → Run transition or full download is required to activate the new protection level).
Security note: Enabling PUT/GET exposes the entire DB area and process image of PLC 2 to any device on the PROFINET subnet that can route to the controller. In a production network, restrict this by using an ACL on the managed switch, a separate VLAN for PLC-to-PLC traffic, or convert to S7-1500 with access-protected program blocks.

Solution 2: Configure Data Block Access Type as Standard

If the data block on PLC 2 that contains the source variable is set to Optimized block access, the absolute byte offset is hidden and PUT/GET cannot address the memory. Reconfigure to standard access.

  1. Open the data block on PLC 2 that holds the variable (for example, DB_Recipe).
  2. Right-click the DB and select Properties.
  3. Under Attributes, uncheck Optimized block access.
  4. Confirm the change. TIA Portal reassigns the absolute offsets; the symbolic names remain intact.
  5. Recompile and re-download the software to PLC 2.

After the change, the variable is addressable as DB_Recipe.DBX0.0 (or whichever byte offset TIA assigned). Capture the byte offset from the Offset column in the DB editor; you need that value to populate the ADDR_i field in the PUT block.

Solution 3: Match ADDR_i and SD_i Area Definitions

The PUT instruction has up to four area pairs (ADDR_1 with SD_1 through ADDR_4 with SD_4). The size of the source area at the partner (ADDR_i) must equal the size of the local data area (SD_i). The size of the read area (RD_i) on the GET instruction must be at least as large as ADDR_i. The data type at the partner and at the local CPU must match byte-for-byte.

PUT Parameter Direction Example Value (PLC 1 → PLC 2) Length
REQ Input (Bool, edge-triggered) %M100.0 1 bit
ID Input (Word) Connection ID from the S7 connection (e.g. 1) 1 word
ADDR_1 Remote (partner) area P#DB_Recipe.DBX0.0 BYTE 2 2 bytes
SD_1 Local source area P#DB_Buffer.DBX0.0 BYTE 2 2 bytes
DONE Output (Bool) %M200.0 1 bit
ERROR Output (Bool) %M200.1 1 bit
STATUS Output (Word) %MW202 1 word

Area length is declared using the pointer literal P#<DB>.DBX<offset> BYTE <count>. Do not pass the data block number alone. For example, to transfer a 2-byte WORD from DB_Recipe starting at byte 0:

P#DB_Recipe.DBX0.0 BYTE 2

The corresponding SD_1 on the local side must also be 2 bytes and the same data type. If the local side is a WORD tag, the partner side must also be a WORD. Type coercion at the S7 communication layer is not performed; the two memory regions must be identical in length.

Solution 4: BOOL-to-WORD Data Type Mapping

A single BOOL is not a valid operand for PUT/GET. There are three field-proven workarounds.

Option A — Pack the BOOL into a WORD using the AT view.


DATA_BLOCK "DB_Recipe"
  STRUCT
    "Running" : BOOL;   // bit 0 of the parent word
  END_STRUCT;
END_DATA_BLOCK

Declare a second variable with the AT attribute pointing to the BOOL array as a WORD:


DATA_BLOCK "DB_Recipe"
  STRUCT
    "Running" : BOOL;
  END_STRUCT;
  "StatusWord" : AT  : WORD;   // overlays the bit 0 of "Running"
END_DATA_BLOCK

Use DB_Recipe.StatusWord in the PUT or GET block. The DB_Recipe.Running tag stays available symbolically for any logic that needs the bit.

Option B — Use a wider data type at source. Change the source variable from BOOL to BYTE, WORD, or DINT and transfer the full element. The receiver extracts the single bit with mask-and-shift logic.

Option C — Convert BOOL to INT (1 = TRUE, 0 = FALSE) in the partner DB and read the INT. The PUT block reads a 2-byte INT and the receiver checks the value rather than the bit.

Why the original fails: When the user assigns a BOOL to SD_1 in the PUT block, the SCL/ST code synthesizes a 1-bit pointer. The partner CPU cannot legally transfer 1 bit — the smallest transferable unit is one byte. TIA Portal will not block the assignment at compile time on firmware V1.x because the check was added in V2.0; the error surfaces at runtime as STATUS = 0x000E or a silent no-op.

Step-by-Step PUT Instruction Configuration

The procedure below configures a PUT block on PLC 1 that copies a 2-byte word from DB_Recipe on PLC 2 to DB_Buffer on PLC 1. The same sequence applies to GET, with the local parameter renamed from SD_i to RD_i.

  1. Define the S7 connection. In Devices & Networks on PLC 1, drag a S7 connection to PLC 2. Confirm the local interface is the PROFINET port, the partner IP is 192.168.0.2, and the connection resource ID is 1 (any free ID > 0).
  2. Insert the PUT block. In PLC 1's main OB (typically OB 1), open the program and drag PUT from the Communication palette into a network. Pick a single instance DB.
  3. Wire the control inputs. Connect REQ to a one-shot rising-edge of a BOOL tag (e.g. %M100.0). Pass the connection ID as a constant 1 to ID.
  4. Define the partner area. On ADDR_1, enter the pointer to the source variable on PLC 2, e.g. P#DB_Recipe.StatusWord (TIA Portal auto-fills the byte length from the data type), or the absolute form P#DB_Recipe.DBX0.0 BYTE 2.
  5. Define the local source area. On SD_1, enter P#DB_Buffer.DBX0.0 BYTE 2. Make sure DB_Buffer on PLC 1 has at least 2 bytes of standard-access storage.
  6. Wire the status outputs. Connect DONE, ERROR, and STATUS to monitoring tags so the block instance can be observed at runtime.
  7. Compile both PLCs. Compile PLC 1, then PLC 2, to verify the cross-project tag references resolve.
  8. Download both PLCs. Stop PLC 2, download hardware + software, run. Stop PLC 1, download hardware + software, run.
  9. Trigger a transfer. Set %M100.0 from the watch table or HMI. Observe DONE rising and STATUS = 16#0000 on success.

Below is a minimal structured-text equivalent for the PUT call on PLC 1, for engineers using SCL:


// One-shot trigger
IF "Trigger_Transfer" AND NOT "Trigger_Latch" THEN
    "Instance_PUT".REQ := TRUE;
ELSE
    "Instance_PUT".REQ := FALSE;
END_IF;
"Trigger_Latch" := "Trigger_Transfer";

// Parameters (configured once in the block instance editor)
// Instance_PUT.ID     := 1
// Instance_PUT.ADDR_1 := P#DB_Recipe.DBX0.0 BYTE 2   (PLC 2 absolute)
// Instance_PUT.SD_1   := P#DB_Buffer.DBX0.0 BYTE 2   (PLC 1 local)

PUT/GET Instruction Parameter Reference

Parameter Declaration Data Type Meaning
REQ INPUT BOOL Trigger pulse; a rising edge starts the transfer
ID INPUT WORD Connection identifier from the S7 connection editor
NDR (GET only) OUTPUT BOOL New data ready (rising edge when fresh data has arrived)
DONE OUTPUT BOOL Transfer completed without error
ERROR OUTPUT BOOL Transfer failed; STATUS contains the cause
STATUS OUTPUT WORD Error code or progress code; 0x0000 on success
ADDR_i (PUT/GET) INPUT Pointer Area at the partner CPU
SD_i (PUT) INPUT Pointer Local source area (PUT writes from local to partner)
RD_i (GET) INPUT Pointer Local destination area (GET writes from partner to local)

A single PUT or GET call supports up to four area pairs. Use multiple calls if you need to transfer more than four disjoint regions. Each call occupies one S7 connection; the S7-1214 supports up to 8 S7 connections in firmware V2.0, 16 in V3.0, and 32 in V4.x.

Verification and Diagnostics

After configuring the PUT or GET block, run the following checks before assuming the link is healthy.

  1. Online → Diagnostics → Connection diagnostics on PLC 1. Confirm the S7 connection to PLC 2 is in state Established and that the partner CPU responds to keep-alive polling.
  2. Watch table on PLC 1: monitor Instance_PUT.STATUS as a hex value. 16#0000 = idle, 16#FFFF = busy, anything else is an error.
  3. Watch table on PLC 2: monitor the absolute byte location of the source tag. Set a known value (e.g. W#16#1234) and verify it is held.
  4. Trigger a transfer: set REQ via the watch table, then read the partner area on PLC 1. The values should match.
  5. Use the trace: in TIA V14 and later, add a trace to PLC 1 with the PUT status word and the local SD_1 data. A successful handshake lasts one OB1 cycle at idle and shows a single STATUS = 0x0000 spike per REQ pulse.

Common Error Codes and Status Bits

STATUS (hex) Meaning Likely Cause Remediation
0x0000 No error / no active job Idle or just completed No action
0x0001 Communication error Partner CPU rejected the request, or remote-access property disabled Enable PUT/GET access on partner CPU Protection tab
0x0002 Negative acknowledgement from partner Partner DB does not exist, or partner memory insufficient Confirm DB number/name exists on partner, length matches
0x000E Target area too small SD_i or RD_i smaller than ADDR_i Equalize the lengths; align on BYTE/WORD/DWORD
0x000F Address of data block invalid DB is optimized, or partner DB number wrong Set DB access to Standard, verify partner DB number
0x0014 Connection busy A previous PUT/GET is still in flight on the same connection Wait for DONE before triggering next REQ, or use a second connection
0x0080 Connection aborted by partner Partner CPU went STOP, or network cable removed Check partner CPU state and physical link
0x00C0 Pointer syntax error ADDR_i or SD_i malformed Re-enter pointer using P#<DB>.DBX<offset> BYTE <count> format
0xFFFF Job in progress Request is being processed Wait for DONE

For a complete listing, refer to the Siemens S7-1200 Programmable Controller System Manual (entry ID 109751826), chapter on S7 communication instructions, and the PUT and GET instruction help page (entry ID 102394124).

Troubleshooting Matrix

Observed Symptom First Check Second Check Third Check
DONE never sets, ERROR = 0 REQ is not a rising edge Connection state is Established STATUS = 0xFFFF indicates busy
ERROR = 1, STATUS = 0x0001 Remote access property on partner Partner CPU is RUN, not STOP Subnet mask matches
ERROR = 1, STATUS = 0x000F Block access is Standard Partner DB number exists Offset within DB size
ERROR = 1, STATUS = 0x000E SD_i length matches ADDR_i length RD_i length ≥ ADDR_i length (GET) Data types match exactly
Compile warning: pointer type mismatch Source tag is BOOL Replace with AT-overlay WORD Re-enter pointer in block editor
Values received but wrong Byte order (big/little endian) Bit indexing within byte Partner DB offset assumption
No data after a Stop/Run of partner Re-download partner HW config Connection ID still valid Check partner IP and PROFINET port

Field-Proven Tips for Mixed-Version Networks

  • When PLC 2 is firmware V2.x and PLC 1 is V4.x, both must be referenced from a TIA Portal version that supports the newer CPU. TIA V13 SP1 with the V4.2 HSP is the minimum.
  • The number of active S7 connections is consumed by HMI, OPC UA server (firmware V4.4+), and PUT/GET in a single pool. With one HMI and one PUT/GET active, an S7-1214 V2.0 has 6 connections left.
  • The PUT block writes from the local CPU to the partner. The GET block reads from the partner to the local. The directional verbs are local-centric; a single CPU may PUT data in one call and GET the same area in a separate call, but you cannot combine them in a single block.
  • If the S7 connection is set to Active connection establishment on PLC 1, PLC 1 initiates the TCP handshake. If you set it to Passive on PLC 1, the partner initiates. Mixing active and passive across two CPUs causes a one-sided state where the connection never establishes.
  • For an S7-1200 target with firmware V2.0, keep total S7 communication cycle load under 50% of OB1 time. PUT/GET with four area pairs at 50 ms scan can saturate the S7 connection on a busy S7-1214.

Do I need to declare the partner variable on PLC 1 in order to use PUT?

No. PUT/GET exchange raw memory areas using absolute byte pointers at the partner CPU. The partner variable only needs to be declared and compiled in PLC 2 with the access type set to Standard. The ADDR_i parameter on the PUT block uses a pointer of the form P#DB_<name>.DBX<offset> BYTE <count> that resolves the partner DB at download time.

Why does the PUT block not find my BOOL variable on PLC 2?

The PUT and GET instructions transfer bytes, not bits. A BOOL tag cannot be the source or destination of a PUT/GET call. Wrap the BOOL in a WORD using an AT overlay, change the source to BYTE/WORD/DINT, or write the BOOL value into an INT (0 or 1) and transfer the INT.

How do I find the absolute address of a variable on PLC 2?

Open the data block on PLC 2 in the TIA Portal, right-click the variable row, and look at the Offset column. For example, if the Offset column shows 2.0, the variable is at byte 2, bit 0. Use that offset in the ADDR_i pointer: P#DB_<name>.DBX2.0 BYTE 1.

What is the meaning of STATUS 0x0001 on a PUT call between two S7-1200 CPUs?

STATUS = 0x0001 indicates a general communication error. The most common cause is that the partner CPU's Permit access with PUT/GET communication from remote partner property is disabled, or the partner CPU is in STOP. Verify the Protection tab on PLC 2 and confirm PLC 2 is in RUN.

Can I keep a data block optimized and still use it for S7 PUT/GET on a S7-1500?

Yes. S7-1500 (and S7-1200 firmware V4.0 and higher) supports optimized blocks for PUT/GET as long as the source tag is reachable by a symbolic or absolute pointer. For S7-1200 firmware V1.x through V3.x, the block must be Standard access because optimized access was not yet introduced on the S7-1200 platform.

Back to blog