Siemens S7-1200 PUT/GET: Limits and Multi-Packet Transfer

David Krause20 min read
S7-1200SiemensTechnical 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

Overview of PUT and GET on the S7-1200

The PUT and GET instructions are the two fundamental blocks of the S7 Communication protocol for SIMATIC S7-1200 CPUs programmed with TIA Portal. They allow a CPU to write (PUT) or read (GET) up to 160 bytes of data from a partner S7 controller without any additional software on the partner side. The partner can be another S7-1200, an S7-1500, an S7-300/400, a WinAC, an ET 200 CPU, or any third-party device that speaks S7 Communication on PROFINET, PROFIBUS, or MPI.

On the S7-1200, PUT and GET are located under Instructions → Communication → S7 Communication once a CPU has been added to the TIA Portal project. No additional library has to be installed; the blocks ship with every TIA Portal installation. The reference document for S7-1200 S7 Communication is the S7-1200 Programmable Controller System Manual, and the architecture-level background is covered in the S7 Communication with PUT/GET application document.

Block Direction Function Max Payload per Call (S7-1200)
PUT Local → Partner Writes SD_1 (and optional SD_2) from the local CPU into ADDR_1 / ADDR_2 of the partner. 160 bytes (SD_1 + SD_2 combined).
GET Partner → Local Reads ADDR_1 (and optional ADDR_2) from the partner into RD_1 / RD_2 of the local CPU. 160 bytes (RD_1 + RD_2 combined).
Asynchronous behavior: PUT and GET are edge-triggered asynchronous blocks. The call is initiated by a rising edge at the REQ input and may take multiple PLC scan cycles to complete. DONE / NDR, ERROR, and STATUS must be evaluated by the user program.

Connection Resources vs. Instruction Count

A frequent point of confusion when starting S7-1200 peer-to-peer programming is whether there is a hard upper limit on the number of PUT or GET instructions that can be placed inside a single user program. TIA Portal does not impose a per-program count limit on PUT or GET instances. The real constraint on an S7-1200 is the number of S7 connections the CPU can manage simultaneously, plus the rule that only one PUT or GET instruction may be active on any given connection resource at any one time. This is the root cause of the "why does my second GET fail?" symptom and the reason the 160-byte payload limit has to be addressed by chunking rather than by simply adding more calls.

How Connections Are Consumed

Every PUT and every GET requires a configured S7 connection that occupies one connection resource on the local S7-1200 and one on the partner. The connection resource is taken as soon as the connection is established (typically at startup or on the first call) and is released only when the partner becomes unreachable and the local CPU's connection watchdog expires.

The number of S7 connections supported by each S7-1200 CPU model is published in the S7-1200 Programmable Controller System Manual. The values that matter for PUT/GET engineering are summarized below. One connection is normally reserved for a programming device (PG), an HMI panel, or TIA Portal online access.

CPU Model Typical Order Number Max S7 Connections (total) Usable for PUT/GET after PG/HMI reservation
CPU 1211C 6ES7211-1BE40-0XB0 / 6ES7211-1AE40-0XB0 3 2
CPU 1212C 6ES7212-1BE40-0XB0 / 6ES7212-1AE40-0XB0 8 7
CPU 1214C 6ES7214-1BG40-0XB0 / 6ES7214-1AG40-0XB0 8 7
CPU 1215C 6ES7215-1BG40-0XB0 / 6ES7215-1AG40-0XB0 16 15
CPU 1217C 6ES7217-1AG40-0XB0 16 15

For a CPU 1212C, eight total S7 connections is the ceiling. This is the value field engineers encounter when they see a project's "max 8 links" property in the S7-1200 connection overview, irrespective of whether the underlying transport is PROFINET, MPI, or PROFIBUS. When you burn all eight slots with PUT/GET, no slot is left for engineering (PG) or HMI online access, so always reserve at least one.

Engineering implication: On a CPU 1212C, if you keep one connection free for the PG/HMI, you can place at most 7 PUT, GET, or other S7-communication-driven blocks. If you need to reach more than 7 partners, upgrade to a CPU 1214C / 1215C / 1217C, or move partner traffic onto Open User Communication over TCP / ISO-on-TCP.

One Active Instruction Per Connection ID

A second, equally important rule applies at runtime: per S7 connection resource, only one PUT or GET may be active at a time. If the user program triggers a second PUT or GET on the same connection ID while the first is still executing, the second call is rejected with one of the following status codes:

  • W#16#8090 – Connection is already in use by another PUT/GET on this CPU.
  • W#16#80C3 – Connection resource not available (depends on firmware).

This is the reason that transferring more than 160 bytes to a single partner requires a sequence of PUT/GET calls on the same connection ID, with each call only started after the previous one has finished.

The 160-Byte Payload Boundary

The S7-1200 PUT instruction transfers at most 160 bytes per call (the sum of SD_1 + SD_2 must not exceed 160). The same applies to GET (RD_1 + RD_2 ≤ 160). The limit is enforced by the S7 Communication framing on the S7-1200 side and is independent of the partner CPU and of the physical transport. The S7-1500 PUT/GET implementation relaxes this bound, but the S7-1200 implementation holds to 160 bytes — confirmed in the field-reference project referenced in Siemens FAQ 65975617.

If you configure a larger SD_1/SD_2 or RD_1/RD_2 area than 160 bytes combined in TIA Portal, the project fails to compile with:

"Length parameter for instruction PUT/GET is invalid. Maximum 160 bytes per call."

To move more than 160 bytes, the user program must split the data into ≤ 160 byte chunks and call PUT or GET multiple times against the same connection ID, with each call handling a different offset of the source and destination area.

Chunk Size Planning

When partitioning a larger block of data, keep each chunk at or below 160 bytes. Aligning to word boundaries (multiples of 2 bytes) keeps the S7-1200 internal bus most efficient. For arrays of REAL / LREAL or structured records, align on 4-byte boundaries.

Total Bytes to Transfer Recommended Chunk Size Number of PUT/GET Calls Final Chunk Bytes
160 160 1 160
320 160 2 160
500 160 4 20
960 160 6 160
2000 (recipe DB) 160 13 80

Prerequisites for PUT/GET on S7-1200

  1. S7-1200 firmware ≥ V4.0 — PUT/GET as currently documented requires firmware V4.0 or higher. For modern TIA Portal projects (V16, V17, V18) use firmware V4.2 or higher. Reference: S7-1200 System Manual.
  2. Permit PUT/GET access on the partner CPU — in TIA Portal, open the partner CPU's properties → Protection & Security → enable "Permit access with PUT/GET communication from remote partner (PLC, HMI, OPC, ...)". Without this option, PUT/GET calls from outside are rejected with status W#16#80A8.
  3. A configured S7 connection in the project's Devices & Networks editor between the local S7-1200 and the partner.
  4. Known TSAPs — S7-1200 slot 1 gives local TSAP 01.01. The default partner TSAP for S7-300/400 is 03.01; for S7-1200/1500 partners it is 03.0x where x is the partner slot (1 for slot 1).
  5. Non-optimized partner blocks — the DBs / M / I / Q areas being read or written must be standard (non-optimized) at the partner. PUT/GET cannot address into optimized S7-1200/S7-1500 DBs by symbolic name; only absolute addresses are accepted.
  6. Sufficient connection resources on both sides per the table above.
  7. Acyclic or cyclic trigger source — for example, a one-shot from the first scan, a button, or a periodic OB1 edge from a clock bit.

Configuring the PUT/GET Connection in TIA Portal

  1. In the project tree, double-click "Devices & Networks".
  2. Drag an S7 connection from the local CPU's port onto the partner CPU's port (or use Add new connection → S7 connection).
  3. In the connection properties, set:
    • Connection type: S7 connection.
    • Local interface: the PROFINET interface of the local S7-1200.
    • Partner interface: the partner's PROFINET interface.
    • Connection path: local subnet (PROFINET) → partner subnet.
    • Connection ID: a free hex value, e.g. W#16#0001. The ID is later referenced as the ID input of the PUT/GET block. Keep it constant and unique per partner.
  4. Click "Compile" and download the hardware configuration to both CPUs.
  5. Verify the connection is established in the partner's Online → Information → Communication view (status = "established").
Tip: Use one connection ID per logical partner, not per PUT/GET instance. Re-using the same connection ID for multiple instructions on the same partner is permitted and is in fact required for the multi-packet chaining pattern described below.

Block Parameters: PUT and GET in Detail

Both PUT and GET share the same fundamental inputs. The difference is the direction of the data flow.

PUT (Send)

Input Data Type Description
REQ BOOL Rising edge starts the PUT job.
ID WORD (W#16#xxxx) Connection ID from "Devices & Networks".
ADDR_1 VARIANT (remote) Pointer to first target area on partner, e.g. P#DB100.DBX0.0 BYTE 160.
ADDR_2 VARIANT (remote) Optional second target area. Omit / leave empty if not needed.
SD_1 VARIANT (local) Pointer to first local source area, e.g. P#DB200.DBX0.0 BYTE 160.
SD_2 VARIANT (local) Optional second local source area.
Output Data Type Description
DONE BOOL TRUE for one cycle when the job completes without error.
ERROR BOOL TRUE for one cycle when the job completes with error.
STATUS WORD Detailed status (W#16#0000 = OK).
BUSY BOOL TRUE while the job is in progress.

GET (Receive)

Input Data Type Description
REQ BOOL Rising edge starts the GET job.
ID WORD Connection ID from "Devices & Networks".
ADDR_1 VARIANT (remote) Pointer to first source area on partner.
ADDR_2 VARIANT (remote) Optional second source area on partner.
RD_1 VARIANT (local) Pointer to first local target area.
RD_2 VARIANT (local) Optional second local target area.
Output Data Type Description
NDR BOOL "New Data Received" — TRUE for one cycle when new data is delivered without error.
ERROR BOOL TRUE for one cycle on error.
STATUS WORD Detailed status.
BUSY BOOL TRUE while the job is in progress.

Programming Multi-Packet Transfers Over 160 Bytes

To transfer a data block larger than 160 bytes, use the same connection ID for a sequence of PUT (or GET) calls, advancing the pointer and offset after each successful chunk. The pattern below instantiates one PUT per chunk with a static P# pointer, then triggers them in order from a small state machine. This pattern compiles cleanly under TIA Portal and avoids runtime Variant manipulation.

State Machine for the Transfer

IDLE CHUNK N DONE? ERROR FINISHED REQ BUSY=true DONE=true ERROR=true REQ+

ST Code Example: Chained PUT of 1000 Bytes

The example below transfers 1000 bytes from local DB200 to partner DB100 on a CPU 1212C, using six PUT calls of 160 bytes and one final call of 40 bytes. All PUT instances share connection ID W#16#0001.

CONST
  cConnId : WORD := W#16#0001;
END_CONST

VAR
  iState   : INT  := 0;       // 0=IDLE, 1..7=chunk index, 99=ERROR, 100=COMPLETE
  xTrigger : BOOL;            // one-shot from caller
  xComplete: BOOL;
  xError   : BOOL;

  // one PUT per chunk — static pointers, static connection ID
  PUT_1 : PUT;
  PUT_2 : PUT;
  PUT_3 : PUT;
  PUT_4 : PUT;
  PUT_5 : PUT;
  PUT_6 : PUT;
  PUT_7 : PUT;

  xDone1..xDone7 : BOOL;
  xErr1..xErr7  : BOOL;
  wStat1..wStat7: WORD;
  xBusy1..xBusy7: BOOL;
END_VAR

// --- 7 PUT calls, 6 x 160 + 1 x 40, all on connection W#16#0001 ---
PUT_1(REQ := (iState = 1) AND NOT PUT_1.BUSY,
      ID := cConnId,
      ADDR_1 := P#DB100.DBX 0.0   BYTE 160,
      SD_1   := P#DB200.DBX 0.0   BYTE 160,
      DONE => xDone1, ERROR => xErr1, STATUS => wStat1, BUSY => xBusy1);

PUT_2(REQ := (iState = 2) AND NOT PUT_2.BUSY,
      ID := cConnId,
      ADDR_1 := P#DB100.DBX 160.0 BYTE 160,
      SD_1   := P#DB200.DBX 160.0 BYTE 160,
      DONE => xDone2, ERROR => xErr2, STATUS => wStat2, BUSY => xBusy2);

PUT_3(REQ := (iState = 3) AND NOT PUT_3.BUSY,
      ID := cConnId,
      ADDR_1 := P#DB100.DBX 320.0 BYTE 160,
      SD_1   := P#DB200.DBX 320.0 BYTE 160,
      DONE => xDone3, ERROR => xErr3, STATUS => wStat3, BUSY => xBusy3);

PUT_4(REQ := (iState = 4) AND NOT PUT_4.BUSY,
      ID := cConnId,
      ADDR_1 := P#DB100.DBX 480.0 BYTE 160,
      SD_1   := P#DB200.DBX 480.0 BYTE 160,
      DONE => xDone4, ERROR => xErr4, STATUS => wStat4, BUSY => xBusy4);

PUT_5(REQ := (iState = 5) AND NOT PUT_5.BUSY,
      ID := cConnId,
      ADDR_1 := P#DB100.DBX 640.0 BYTE 160,
      SD_1   := P#DB200.DBX 640.0 BYTE 160,
      DONE => xDone5, ERROR => xErr5, STATUS => wStat5, BUSY => xBusy5);

PUT_6(REQ := (iState = 6) AND NOT PUT_6.BUSY,
      ID := cConnId,
      ADDR_1 := P#DB100.DBX 800.0 BYTE 160,
      SD_1   := P#DB200.DBX 800.0 BYTE 160,
      DONE => xDone6, ERROR => xErr6, STATUS => wStat6, BUSY => xBusy6);

PUT_7(REQ := (iState = 7) AND NOT PUT_7.BUSY,
      ID := cConnId,
      ADDR_1 := P#DB100.DBX 960.0 BYTE 40,
      SD_1   := P#DB200.DBX 960.0 BYTE 40,
      DONE => xDone7, ERROR => xErr7, STATUS => wStat7, BUSY => xBusy7);

// --- State machine advances on DONE; ERROR aborts and logs wStat ---
CASE iState OF
  0:
    IF xTrigger THEN iState := 1; END_IF;
  1:
    IF xDone1 THEN iState := 2;
    ELSIF xErr1 THEN iState := 99; END_IF;
  2:
    IF xDone2 THEN iState := 3;
    ELSIF xErr2 THEN iState := 99; END_IF;
  3:
    IF xDone3 THEN iState := 4;
    ELSIF xErr3 THEN iState := 99; END_IF;
  4:
    IF xDone4 THEN iState := 5;
    ELSIF xErr4 THEN iState := 99; END_IF;
  5:
    IF xDone5 THEN iState := 6;
    ELSIF xErr5 THEN iState := 99; END_IF;
  6:
    IF xDone6 THEN iState := 7;
    ELSIF xErr6 THEN iState := 99; END_IF;
  7:
    IF xDone7 THEN iState := 100;
    ELSIF xErr7 THEN iState := 99; END_IF;
  99:
    // ERROR — log wStatN for the failed chunk, raise xError
    xError := TRUE;
    // operator reset brings iState back to 0 after acknowledgement
  100:
    xComplete := TRUE;
    xTrigger  := FALSE;
    iState    := 0;
END_CASE;
Practical pointer handling: The seven static PUT instances above cover the entire 1000-byte range. If the partner DB length changes, only the number of PUT instances and the BYTE lengths need to be edited. For a fully parameterized number of chunks, build the offsets at runtime via P# Variant arithmetic in a single multi-instance DB, but be aware that Variant constructors in TIA Portal ST are constrained to literals at compile time for the ADDR_1 / SD_1 inputs of the standard PUT block. See the official Siemens FAQ "How do you program the GET and PUT instructions in the user program of the SIMATIC S7-1200 CPU in order to transfer more than 160 bytes of data?" for the canonical sample project download.

ST Code Example: Chained GET of 1000 Bytes

The GET side mirrors the PUT side. The only differences are the pointers (RD_1 instead of SD_1) and the use of the NDR (New Data Received) bit instead of DONE.

CONST
  cConnId : WORD := W#16#0001;
END_CONST

VAR
  iState   : INT  := 0;
  xTrigger : BOOL;
  xComplete: BOOL;
  xError   : BOOL;

  GET_1 : GET;  // bytes 0..159   from partner DB100 into local DB200
  GET_2 : GET;  // bytes 160..319
  GET_3 : GET;  // bytes 320..479
  GET_4 : GET;  // bytes 480..639
  GET_5 : GET;  // bytes 640..799
  GET_6 : GET;  // bytes 800..959
  GET_7 : GET;  // bytes 960..999 (40 bytes)

  xNdr1..xNdr7 : BOOL;
  xErr1..xErr7 : BOOL;
  wStat1..wStat7 : WORD;
  xBusy1..xBusy7 : BOOL;
END_VAR

GET_1(REQ := (iState = 1) AND NOT GET_1.BUSY,
      ID := cConnId,
      ADDR_1 := P#DB100.DBX 0.0   BYTE 160,
      RD_1   := P#DB200.DBX 0.0   BYTE 160,
      NDR => xNdr1, ERROR => xErr1, STATUS => wStat1, BUSY => xBusy1);

GET_2(REQ := (iState = 2) AND NOT GET_2.BUSY,
      ID := cConnId,
      ADDR_1 := P#DB100.DBX 160.0 BYTE 160,
      RD_1   := P#DB200.DBX 160.0 BYTE 160,
      NDR => xNdr2, ERROR => xErr2, STATUS => wStat2, BUSY => xBusy2);

GET_3(REQ := (iState = 3) AND NOT GET_3.BUSY,
      ID := cConnId,
      ADDR_1 := P#DB100.DBX 320.0 BYTE 160,
      RD_1   := P#DB200.DBX 320.0 BYTE 160,
      NDR => xNdr3, ERROR => xErr3, STATUS => wStat3, BUSY => xBusy3);

GET_4(REQ := (iState = 4) AND NOT GET_4.BUSY,
      ID := cConnId,
      ADDR_1 := P#DB100.DBX 480.0 BYTE 160,
      RD_1   := P#DB200.DBX 480.0 BYTE 160,
      NDR => xNdr4, ERROR => xErr4, STATUS => wStat4, BUSY => xBusy4);

GET_5(REQ := (iState = 5) AND NOT GET_5.BUSY,
      ID := cConnId,
      ADDR_1 := P#DB100.DBX 640.0 BYTE 160,
      RD_1   := P#DB200.DBX 640.0 BYTE 160,
      NDR => xNdr5, ERROR => xErr5, STATUS => wStat5, BUSY => xBusy5);

GET_6(REQ := (iState = 6) AND NOT GET_6.BUSY,
      ID := cConnId,
      ADDR_1 := P#DB100.DBX 800.0 BYTE 160,
      RD_1   := P#DB200.DBX 800.0 BYTE 160,
      NDR => xNdr6, ERROR => xErr6, STATUS => wStat6, BUSY => xBusy6);

GET_7(REQ := (iState = 7) AND NOT GET_7.BUSY,
      ID := cConnId,
      ADDR_1 := P#DB100.DBX 960.0 BYTE 40,
      RD_1   := P#DB200.DBX 960.0 BYTE 40,
      NDR => xNdr7, ERROR => xErr7, STATUS => wStat7, BUSY => xBusy7);

CASE iState OF
  0:
    IF xTrigger THEN iState := 1; END_IF;
  1: IF xNdr1 THEN iState := 2;  ELSIF xErr1 THEN iState := 99; END_IF;
  2: IF xNdr2 THEN iState := 3;  ELSIF xErr2 THEN iState := 99; END_IF;
  3: IF xNdr3 THEN iState := 4;  ELSIF xErr3 THEN iState := 99; END_IF;
  4: IF xNdr4 THEN iState := 5;  ELSIF xErr4 THEN iState := 99; END_IF;
  5: IF xNdr5 THEN iState := 6;  ELSIF xErr5 THEN iState := 99; END_IF;
  6: IF xNdr6 THEN iState := 7;  ELSIF xErr6 THEN iState := 99; END_IF;
  7: IF xNdr7 THEN iState := 100; ELSIF xErr7 THEN iState := 99; END_IF;
  99:
    xError := TRUE;
  100:
    xComplete := TRUE;
    xTrigger  := FALSE;
    iState    := 0;
END_CASE;

Status and Error Code Reference

The STATUS output of PUT/GET follows the W#16# convention. The values most commonly encountered on S7-1200 S7 Communication are listed below. A complete reference is published in the S7-1200 System Manual.

STATUS (W#16#) Meaning Cause / Remedy
0000 Job completed without error DONE / NDR was set; advance to next chunk.
7000 Call with REQ = 0, no job active Normal idle state.
7001 First call with REQ = 1, job started Wait for completion.
7002 Subsequent call while job still running Normal during a multi-cycle job.
8090 Connection already in use by another PUT/GET on this CPU Serialize calls on the same connection ID.
8091 Connection not yet established Wait for partner online, or recheck "Permit PUT/GET access".
80A0 Negative acknowledgment from partner Partner rejected the access; check TSAP and partner area validity.
80A8 Partner CPU does not permit PUT/GET Enable "Permit access with PUT/GET communication" on the partner.
80B0 Pointer syntax error Invalid P# literal; check area, byte offset, length.
80B1 Length exceeds 160 bytes (SD_1+SD_2 or RD_1+RD_2) Reduce chunk size or split into two calls.
80C3 Connection resource exhausted on local or partner CPU Reduce the number of active S7 connections; see resource table.
80D0 / 80D1 Partner CPU in STOP / partner protection violation Bring partner to RUN; review access protection.

Verification

After commissioning, verify the multi-packet transfer with the following checks:

  1. Online → Accessible nodes in TIA Portal — confirm both CPUs are visible on PROFINET and the S7 connection shows status "Established".
  2. Watch table on both sides — write a marker pattern into the local source DB, trigger the transfer, and confirm the pattern appears in the partner DB (and vice versa for GET).
  3. Monitor PUT_Instance.STATUS — after the final call, STATUS should be 0000 and BUSY should be 0.
  4. Forced error test — temporarily misconfigure the partner TSAP to provoke W#16#80A0 and confirm the ERROR path is taken and the application does not deadlock.
  5. Resource check — open Online → Information → Communication on each CPU and verify that the number of "Established" connections matches the expected sum of PG + HMI + PUT/GET partners, with at least one slot free on a CPU 1212C for engineering access.

Alternative Approaches

If the 160-byte limit or the S7 connection count becomes a hard blocker on a CPU 1212C, two alternatives are commonly used.

Open User Communication over TCP / ISO-on-TCP

S7-1200 firmware V4.0 and higher supports Open User Communication via the TCON, TSEND, TRCV, and TDISCON blocks. There is no 160-byte per-call limit — TSEND/TRCV transfers up to 8192 bytes per call. The protocol is generic TCP, not S7 Communication, so the partner can be any device that opens a TCP socket. This is the recommended path when (a) the partner is not a Siemens S7 CPU, or (b) very large payloads need to be moved between two S7-1200 CPUs without burning S7 connection resources. The TCP-based path does not count against the S7 connection resource limit.

Upgrade to a Larger CPU

If S7 Communication is mandatory (for example, because the partner is an S7-300/400 or S7-1500 with no native TCP listener), moving from a CPU 1212C (8 S7 connections) to a CPU 1214C (8 S7 connections) does not help — only a 1215C or 1217C (16 S7 connections) doubles the available S7 connection resources without changing the program structure.

Field-Engineering Notes

  • Optimized blocks: PUT/GET cannot write into S7-1500 optimized DBs by symbolic name. Use the absolute address (DB number + offset + length) when configuring ADDR_1 / ADDR_2.
  • CPU 1212C "8 links": The "8 links" ceiling commonly quoted for the CPU 1212C is the total S7 connection count, not the per-block instruction count. Burning all eight slots with PUT/GET leaves no room for an HMI; reserve at least one for commissioning access.
  • Buffering at the partner: For cyclic data with high update rates, add handshake bits so the partner only consumes a chunk after the entire frame has been received. PUT/GET has no built-in frame-completion indication.
  • Firmware ≥ V4.2: Siemens has tightened security defaults in recent firmware; if the S7-1200 CPU has the "Permit access with PUT/GET" option cleared (default in V4.4 and higher with security settings), all PUT/GET calls return W#16#80A8 until the option is re-ticked and the project re-downloaded.
  • Timeouts and retries: If a chunk fails (ERROR=1), the application must decide whether to retry from the failed chunk or restart at offset 0. Re-issuing the same PUT after the partner recovers is usually safe because PUT is idempotent on the same offsets.
  • TSAP slot offset: When the S7-1200 sits in slot 1, the default partner TSAP is 03.01. If you stack a second S7-1200 in slot 2 of the same rack, use 03.02; for ET 200SP CPUs in slot 1 of a distributed station, the partner TSAP is still 03.01 as seen from the PROFINET view.

Frequently Asked Questions

How many GET instructions can I place in an S7-1200 user program?

There is no per-program instruction-count limit on PUT/GET. The real limit is the number of S7 connections the CPU can manage. A CPU 1212C supports 8 total S7 connections (1 typically reserved for PG/HMI), so you can place at most 7 active PUT/GET instances across all partners. Only one PUT or GET may be active on a given connection ID at any time.

What is the maximum payload for a single PUT or GET call on an S7-1200?

160 bytes, the total of SD_1+SD_2 for PUT and RD_1+RD_2 for GET. Any configuration larger than 160 bytes is rejected at compile time. To move more data, split it into chunks of ≤ 160 bytes and chain calls on the same connection ID. See the official Siemens FAQ 65975617 for a sample project.

Why does my S7-1200 return status W#16#80A8 on PUT/GET?

The partner CPU has the "Permit access with PUT/GET communication from remote partner" option disabled. Open the partner's properties → Protection & Security → tick the box and re-download the configuration.

Why does my second PUT on the same connection ID fail with W#16#8090?

Per connection ID, only one PUT or GET may be active at a time. W#16#8090 indicates the connection is already in use. Serialize the calls in the user program (state machine) so each call starts only after the previous one's DONE / NDR has been observed.

Can I use PUT/GET to write into an optimized DB on an S7-1500 partner?

No. PUT/GET requires absolute addresses (P#DB100.DBX0.0 BYTE n). Optimized S7-1500 DBs can still be addressed absolutely by their DB number, but the offsets inside the DB must be known at compile time. The simplest path is to keep the partner DB non-optimized for any PUT/GET-accessed area.

Back to blog