Application Overview
This reference describes a complete PROFINET-based data exchange between two SIMATIC S7-1200 CPUs (article number 6ES7 215-1HG40-0XB0, CPU 1215C DC/DC/DC, firmware V4.x) using the PUT and GET instructions in TIA Portal V15.1. The architecture is a typical level-control application: one CPU reads a 4–20 mA level transmitter, the second CPU consumes the same process variable and re-emits it on a 4–20 mA analog output. The two CPUs exchange the level value as a 16-bit integer (or as a real engineering value) over a single S7 connection routed through the onboard PROFINET interface of each CPU.
Key engineering points covered:
- Single TIA Portal project with two devices, one S7 connection
- PUT/GET access must be explicitly enabled under Protection & Security (firmware V4.x and later)
- Data blocks used for PUT/GET must be non-optimized (standard access)
- Analog normalization with
NORM_XandSCALE_X - Evaluation of
ERRORandSTATUSoutputs for diagnostics
Prerequisites and Hardware
| Item | Specification | Article / Version |
|---|---|---|
| CPU A (sensor side) | SIMATIC S7-1215C DC/DC/DC, 14 DI / 10 DO / 2 AI onboard | 6ES7 215-1HG40-0XB0, FW ≥ V4.2 |
| CPU B (output side) | SIMATIC S7-1215C DC/DC/DC, 14 DI / 10 DO / 2 AI onboard | 6ES7 215-1HG40-0XB0, FW ≥ V4.2 |
| Engineering tool | STEP 7 Professional V15.1, Update 4 or later | 6ES7 822-1AA05-0YA5 |
| Switch / cable | PROFINET-compliant, 100 Mbit/s, Cat 5e minimum | — |
| Level transmitter | 2-wire, 4–20 mA, 12–30 V loop powered | site-specific |
| Analog output module | SM 1232 AQ 4×14 bit (if no onboard AO present) | 6ES7 232-4HD32-0XB0 |
6ES7 231-4HA30-0XB0, 1 AI, 0–20 mA) or wire a precision 500 Ω shunt across the AI terminal and use the 0–10 V input range. The 4 mA live-zero is then handled in software.
Verify PROFINET cabling pinout (RJ-45, T-568B) and that the CPUs are powered, the PROFINET LEDs (LINK, RX/TX) are green steady, and that both CPUs are reachable from the PG/PC.
Project Setup and IP Configuration
- Open TIA Portal V15.1 and create a new project. Add both CPUs from the hardware catalog: Controllers → SIMATIC S7-1200 → CPU → CPU 1215C DC/DC/DC → 6ES7 215-1HG40-0XB0. Insert each CPU into its own device.
- For each CPU, open Properties → PROFINET interface [X1] → Ethernet addresses and assign a unique IP and PROFINET device name. A working pair for a small system:
CPU IP address Subnet mask PROFINET name PLC_1 (sensor) 192.168.0.10 255.255.255.0 plc1-level PLC_2 (output) 192.168.0.11 255.255.255.0 plc2-ao - Assign the PROFINET device name to each CPU online via Online → Accessible devices → Assign PROFINET device name. A blank PROFINET name will prevent the connection from coming up.
- Save and compile each device. Verify that the device configuration is downloaded without errors (no red entries in the Inspector).
Configuring the PROFINET S7 Connection
Switch to the Devices & Networks editor. The two CPUs are on the same PROFINET subnet. Right-click the PROFINET port of PLC_1 and choose Add new connection → S7 connection. The partner should be PLC_2. The connection is automatically created as a point-to-point S7 connection.
- In the connection properties, confirm the local endpoint = PLC_1, partner endpoint = PLC_2, and that Establish active connection is set on PLC_1 (the PUT/GET initiator). For GET it does not matter which side is active; the connection establishment flag only controls who opens the TCP/ISO-on-TCP socket.
- The connection ID is assigned by TIA Portal and is needed for the PUT/GET block parameters. Note the
IDvalue (a hex word such asW#16#0001) — do not change it manually. - Compile the network and download the connection configuration to both CPUs.
STATUS = 0x0001 on PUT/GET usually means the connection table is full or the partner is unreachable, not a programming fault.
Enabling PUT/GET Remote Access
Since firmware V4.x, the CPU 1215C blocks remote PUT/GET access by default. The security setting is not in General and not under Communication — it sits under Protection & Security and is a CPU-wide authorization, not a per-connection option.
- Select the CPU in the project tree → Properties → Protection & Security → Connection mechanisms.
- Tick Permit access with PUT/GET communication from remote partner (PLC, HMI, OPC, …).
- Repeat on the second CPU.
- Recompile and re-download the hardware configuration to both CPUs (a STOP/START or a RUN re-init of the connection is required for the new security context to take effect).
STATUS output of the local PUT/GET instruction returns a security-related error (typically 0x0001 with no error bit on the connection itself). Many hours of field debugging have been lost to this single check-box.
Data Block Configuration for PUT/GET
Both CPUs must expose a data block with the same absolute byte layout. PUT and GET transfer a contiguous byte range addressed by an absolute offset, so any padding, alignment, or symbol-only tag in an optimized block will break the transfer.
- Create a new global DB in each CPU. In Properties → Attributes uncheck Optimized block access (the access mode must be Standard – compatible with S7-300/400).
- Define the data layout identically in both PLCs. Recommended structure for a level transfer:
| Symbol | Type | Byte offset | Comment |
|---|---|---|---|
| Level_Raw | INT | 0.0 | Normalized raw count from AI (0–27648) |
| Level_Eng | REAL | 2.0 | Scaled engineering value (e.g. 0.0–100.0 %) |
| Level_Status | WORD | 6.0 | Quality / comms heartbeat (user-defined) |
| Reserve | BYTE | 8.0 | Padding to 10-byte boundary |
| Length | — | 10 bytes | PUT/GET length parameter |
Right-click the DB in the project tree and select Block properties → Information → Offset to confirm the start address is the expected DB100, for example, with the first byte at P#DB100.DBX0.0 BYTE 10.
PUT Instruction Implementation
The PUT instruction writes a contiguous byte range from the local DB into the same offset of the partner DB. In PLC_1 (sensor), call PUT in a cyclic OB (OB1 or OB30…OB38):
// FB / FC call in OB1 - PLC_1 (PUT to PLC_2)
iPUT_DB : "PUT_DB"; // instance DB auto-generated
REQ :=%M10.0; // rising edge to trigger write
ID :=W#16#0001; // connection ID from Devices & Networks
DONE =>%M10.1;
ERROR =>%M10.2;
STATUS =>%MW12;
ADDR_1 :=P#DB100.DBX0.0 BYTE 10; // partner DB (PLC_2) start address
SD_1 :=P#DB100.DBX0.0 BYTE 10; // local DB start address
LEN :=10; // byte length
Key behavior:
-
REQtriggers a one-shot write. Drive it from a clock-bit or a rising edge — driving it level-true sends continuously and may saturate the connection table. -
DONE= 1 for one cycle after success.ERROR= 1 with non-zeroSTATUSon failure. - The local
SD_1and the partnerADDR_1must point at DBs with identical byte layout.
GET Instruction Implementation
On the consumer side (PLC_2), GET reads the partner DB into a local DB. If you keep the data flow one-directional (sensor → output) the GET is optional; it is needed when the output CPU must also re-transmit the value or when you build a heartbeat echo for diagnostics.
// FB / FC call in OB1 - PLC_2 (GET from PLC_1)
iGET_DB : "GET_DB";
REQ :=%M20.0;
ID :=W#16#0001; // same connection ID
DONE =>%M20.1;
ERROR =>%M20.2;
STATUS =>%MW22;
ADDR_1 :=P#DB100.DBX0.0 BYTE 10; // partner DB (PLC_1)
RD_1 :=P#DB100.DBX0.0 BYTE 10; // local DB
LEN :=10;
Because PUT already writes to PLC_2's local DB, a symmetric GET on PLC_2 is rarely required. The configuration in Devices & Networks is one S7 connection, not two — the direction of data is determined by the call, not by the connection.
Analog Input Scaling (4–20 mA Level Sensor)
With a 0–20 mA input range (SB 1231 or 500 Ω shunt + 0–10 V) the raw integer from %IW64 is the Siemens standard range 0–27648. To convert to a 0.0–100.0 % engineering value:
// NORM_X: raw count -> normalized 0.0 .. 1.0
%DB100.DBX0.0 := "Level_Raw"; // INT, written by MOVE from %IW64
// SCALE_X: 0.0 .. 1.0 -> 0.0 .. 100.0 %
"SCALE_DB"( // instance from SCALE_X / NORM_X library
VALUE := NORM_X(MIN :=0, VALUE := "Level_Raw", MAX :=27648),
MIN := 0.0,
MAX := 100.0,
OUT => "Level_Eng");
For a tank with live-zero suppression (level = 4 mA at empty, 20 mA at full) use SCALE_X with the engineering range you actually need (e.g. 0.0–5.0 m) and configure the AI to 4–20 mA if your hardware supports it directly. Live-zero break detection: if the raw count falls below 0 or above 32511, treat the value as bad and freeze the analog output to its failsafe state.
Analog Output Scaling and Writeback
On PLC_2, the consumed Level_Eng is scaled back into the AO range 0–27648 and written to the SM 1232 output word:
// SCALE_X: 0.0 .. 100.0 % -> 0 .. 27648
"Level_AO_Raw" := SCALE_X(
VALUE := NORM_X(MIN :=0.0, VALUE := "Level_Eng", MAX :=100.0),
MIN :=0,
MAX :=27648);
%QW64 := "Level_AO_Raw"; // SM 1232 channel 0
%QW64. The AO expects a 0–27648 integer. A floating-point write is accepted by the editor but interpreted as undefined and may drive the output to full scale.
Error Handling and STATUS Evaluation
PUT and GET expose ERROR (BOOL) and STATUS (WORD). A common error-handling block in SCL:
IF "iPUT_DB".ERROR THEN
CASE "iPUT_DB".STATUS OF
16#0001: // connection faulted or partner unreachable
"Comms_Fault" := TRUE;
16#0002: // negative acknowledgement from partner
"Partner_NAK" := TRUE;
16#0007: // PUT/GET access disabled on partner
"PutGet_Blocked" := TRUE;
16#0081: // partner in STOP
"Partner_STOP" := TRUE;
16#80C3: // resource problem - too many active jobs
"Resource_Busy" := TRUE;
ELSE
"Comms_Unknown" := TRUE;
END_CASE;
END_IF;
IF "iPUT_DB".DONE THEN
"Comms_Fault" := FALSE;
"Partner_NAK" := FALSE;
"PutGet_Blocked" := FALSE;
"Partner_STOP" := FALSE;
"Resource_Busy" := FALSE;
"Comms_Unknown" := FALSE;
END_IF;
Field-proven detail: GET1.ERROR does not change state the moment you pull the Ethernet cable. The CPU keeps the connection alive for several seconds; ERROR only rises when the next REQ triggers a job that times out. Drive a watchdog in OB35 that triggers PUT/GET cyclically — without a periodic REQ, the error flags will stay stuck at 0 even when the cable is disconnected. This is the most common source of the symptom "I pull the cable and nothing happens in the error byte."
Connection Diagnostics and Online View
Use Online & Diagnostics → Diagnostics → Connection information on the CPU to inspect every S7 connection, its state, and the last error code. TIA Portal displays the connection in three states:
- Established – PUT/GET is allowed, no error pending.
-
Not established – connection is configured but not yet open. The CPU will try to establish on first
REQ. - Faulted – last attempt failed. The error reason is shown in the connection details.
For PROFINET-level diagnostics, open Online → Accessible devices, select the partner CPU, and read the port statistics for CRC, discard, and Late Collision counters.
Verification and Commissioning
- Download both station configurations and user programs. Both CPUs should be in RUN, the
RUN/STOPLED green, and theLINKLED on the PROFINET port solid green on each device. - Force a small value into
Level_Rawin PLC_1 (e.g. 13824, ≈ 50 %) and verify thatLevel_Engin PLC_2 reads 50.0 (or your calibrated engineering unit) within one PUT cycle. With OB1, this is < 100 ms. - Measure the analog output on PLC_2 with a mA meter. The reading should be 12.00 mA for a 50 % level, 4.00 mA at empty, 20.00 mA at full.
- Disconnect the PROFINET cable on PLC_1 side. Within the watchdog interval,
Comms_Faultshould rise. Reconnect; verify thatComms_Faultclears and the AO resumes tracking. - Save the project as a reference revision and export the HMI tag list / connection list for documentation.
Troubleshooting Matrix
| Symptom | Likely cause | Countermeasure |
|---|---|---|
| PUT/GET DONE never true, ERROR = 1, STATUS = 16#0001 | PUT/GET blocked on partner CPU | Enable Permit access with PUT/GET communication from remote partner on both CPUs and re-download |
| STATUS = 16#0081, partner LED shows STOP | Partner CPU not in RUN | Start partner; verify wiring of the mode selector |
| STATUS = 16#0007, no error on partner online view | Connection not configured, wrong connection ID | Re-create the S7 connection in Devices & Networks, recompile, re-download to both CPUs |
| Error stays at 0 when cable is unplugged | PUT/GET not triggered cyclically | Drive REQ from a clock bit (e.g. 1 Hz) or call PUT/GET in OB35 |
| Data values arrive but are swapped / wrong bytes | Optimized DB on one side, non-optimized on the other | Set both DBs to Standard – compatible with S7-300/400 and recompile |
| AI reads 0, level sensor not detected | Wrong input range, sensor powered in reverse, missing 500 Ω shunt | Check the AI configuration in Properties → Analog inputs (0–10 V vs 0–20 mA), verify loop power |
| AO stuck at full scale (20 mA) | REAL value written to %QW64 by mistake | Insert a SCALE_X → INT conversion before the AO assignment |
| Connection list shows the connection as "Not established" forever | PROFINET device name missing or duplicated | Assign unique PROFINET names; verify with Online → Accessible devices |
| STATUS = 16#80C3, intermittent failures | Too many concurrent PUT/GET jobs / HMI traffic | Reduce HMI polling, gate PUT/GET to OB35, check number of open S7 connections |
Related Documentation
The procedure and the connection behavior are documented in the Siemens application note S7 communication between SIMATIC S7-1200 and SIMATIC S7-1500 (entry ID 82212115). The same connection mechanism applies to S7-1200 ↔ S7-1200 and to PUT/GET over an S7 connection. The S7-1200 system manual covers the security option for PUT/GET in firmware V4.x and the requirement to use non-optimized data blocks for absolute addressing.
Do I have to enable PUT/GET access on every S7-1200 firmware V4.x CPU?
Yes. Since firmware V4.0 the security option Permit access with PUT/GET communication from remote partner in Protection & Security → Connection mechanisms is disabled by default on the S7-1200. It must be enabled on both CPUs and the hardware configuration re-downloaded for the change to take effect.
Why does GET1.ERROR stay 0 when the Ethernet cable is unplugged?
Because GET only sets ERROR on the next REQ-triggered job. Without a periodic trigger the CPU keeps the previous successful state. Drive REQ from a clock bit (for example 1 Hz) or call GET inside a cyclic OB such as OB35 so a time-out is forced when the link drops.
Why are my data bytes swapped or wrong even though the program compiles?
One of the two data blocks is optimized. PUT/GET transfers raw bytes by absolute offset, so both DBs must use the Standard – compatible with S7-300/400 access mode and the byte layout must be identical on both CPUs.
Can I use PROFINET IO data exchange instead of PUT/GET?
For two S7-1200 CPUs in a flat topology the simpler approach is the S7 connection with PUT/GET, as documented in S7 communication between S7-1200 and S7-1500. PROFINET IO (controller/device) is appropriate only when one CPU is the PROFINET controller and the other behaves as an I-device.
What raw count range does the analog input use for 4–20 mA?
The Siemens S7-1200 analog channels use 0–27648 as the nominal range. With a 500 Ω shunt and the 0–10 V input range, 4 mA becomes ≈ 2.0 V = 5530 counts and 20 mA becomes 10.0 V = 27648 counts. Use NORM_X with MIN = 0, MAX = 27648 (or MIN = 5530 if you want 4 mA = 0 %) and then SCALE_X to your engineering range.