Problem Summary and Symptoms
A SIMATIC S7-300 station built around a CPU 317-2 DP (Siemens order number 6ES7317-2AK14-0AB0) reads a thermocouple temperature through a 4-20 mA head-mounted transmitter. The 4-20 mA loop terminates at a Wago 750-474 four-channel analog input module mounted on a Wago 750 Series Profibus slave coupler. The field value lands in the S7-300 process image at PIW 176 (channel 0, raw 16-bit count) but never shows up in the application data block at DB24.DBD16, where the InTouch Wonderware SCADA expects a scaled, 32-bit REAL temperature value.
Three concrete symptoms appear in the source case:
- The value seen at
PIW 176in online monitoring is correct, butDB24.DBD16remains at0.0(or stale) on every cycle. - When the operator forces
PIW 176above+127decimal, the SCADA value goes negative instead of continuing to climb. - The only candidates that could plausibly write to
DB24.DBD16areFC161andFC166; both are know-how protected and cannot be inspected without first un-locking them in STEP 7.
All three symptoms point to a single architectural gap: there is no FC or FB in the user program that bridges the S7 process image and the application DB, and the two candidates that could do that work are protected.
Hardware Topology and Signal Path
The end-to-end signal path is:
The Wago coupler is a Profibus-DP slave. Its GSD file (WAGO_750 family) is installed in STEP 7 / HW Config. After DP slave address assignment (for example, station 7) and slot configuration, the analog channel occupies a fixed PIW window on the CPU. In this case the integrator chose PIW 176 as the input word for channel 0.
The S7-300 is then expected to:
- Read the raw 0-27648 (or 0-32767) count from
PIW 176. - Scale the count into engineering units (°C, °F, bar, …).
- Apply any correction (ABS, deadband, averaging).
- Deposit the final REAL value in
DB24.DBD16for SCADA handover.
Step 4 is what is missing in the source program.
CPU 317-2DP and Wago 750-474 Specifications
| Item | Value | Notes |
|---|---|---|
| CPU order number | 6ES7317-2AK14-0AB0 | CPU 317-2DP, work memory 1 MB code / 2 MB data, MPI + 2× Profibus-DP master/slave |
| Profibus interfaces | DP-M / DP-S (X1), DP-M (X2) on -2DP variants | Two bus-fault LED groups: BF, BF1, BF2 |
| Process image size | configurable; PIW0…PIW255 typical | PIW 176 is within default 128-word window if extended |
| Wago 750-474 | 4-channel analog input, 0-10 V / ±10 V / 0-20 mA / 4-20 mA / Pt / Ni / Thermo | 16-bit resolution, channel-by-channel configurable via Wago I/O CHECK or GSD |
| Wago Profibus coupler | 750-333 (Profibus DP/V1, DPV1 class 2) or 750-303 (DP/V0) | Hosts the modular 750 Series terminal block |
| Raw count scaling (4-20 mA) | 0 mA = 0; 20 mA = 27648 (Siemens normalization) or 32767 (Wago native) | Critical for negative-value diagnosis below |
The official SIMATIC S7-300 CPU 315-2 DP / CPU 317-2 DP manual describes the BF / BF1 / BF2 LED layout and pin-out that is referenced when validating that the Wago slave is actually exchanging process data with the CPU. Confirm that BF is OFF on the CPU before assuming the PIW is valid. See the Siemens manual portal at SIMATIC S7-300 CPU 317-2 DP manual on support.industry.siemens.com.
Profibus I/O Address Mapping for PIW 176
Profibus-DP slave I/O addresses in S7-300 are not assigned dynamically; they are calculated at HW-config compile time and frozen in the system data (SDB). For a Wago 750 coupler with an analog input submodule starting at slot 2, the starting PIW is determined by the order in which modules are inserted and the configured I/O area.
If PIW 176 is the start of channel 0, then channels 1-3 occupy:
| Channel | Peripheral address | Byte offset | Data type |
|---|---|---|---|
| 0 | PIW 176 | PQB 176/177 | INT (16-bit) |
| 1 | PIW 178 | PQB 178/179 | INT (16-bit) |
| 2 | PIW 180 | PQB 180/181 | INT (16-bit) |
| 3 | PIW 182 | PQB 182/183 | INT (16-bit) |
Root Cause Analysis
Three independent root causes line up to explain the behavior:
-
Missing bridging logic. The user program loads
PIW 176into a TEMP variable inFC161(segment 12 is the only place that touchesDB24), but there is no instruction that copies the scaled real value intoDB24.DBD16.DBD 16is a 4-byte REAL slot spanning bytes 16-19. Without an explicitT DB24.DBD16, the slot retains its initialized value of0.0. -
Know-how protection on FC161 / FC166. STEP 7 know-how protection hides the code body but does not prevent the block from running. The integrator cannot see where
DB24.DBD16is written because the body is encrypted. The only way to map the data path is either to (a) remove the protection, (b) instrument the DB with aSTIME/watchdog, or (c) insert a brand-new FC that performs the transfer explicitly. -
Signed-int wrap on 8-bit-perceived boundary. Going negative at
+127indicates that the user is observing the high byte of the WORD as a signed 8-bit value (S7 status display shows it as INT), or the scaling math divides by a base that becomes negative when the numerator crosses 127. In STEP 7, the default monitor format forPIWis INT (signed 16-bit), but PIW 176 in the Wago 0-20 mA range is an unsigned 0-27648 count. Display format alone should not flip sign — the most likely cause is thatDB24.DBD16is being written as REAL and the source INT is interpreted as signed.
Combined, the data is available in PIW 176 but never delivered to DB24.DBD16, and the SCADA therefore reads stale data.
STL Implementation: Building the Missing FC Block
The fastest path to a working handover is to add a new FC — for example FC200 — that owns the PIW-to-DB transfer. Wire it from OB1 or OB35 (cyclic interrupt at 100 ms is typical for thermal loops).
Network 1 — Read raw count from PIW 176
FUNCTION FC 200 : VOID
TITLE = 'AI0 PIW176 to DB24.DBD16 with ABS'
VERSION : 0.1
VAR_TEMP
tRaw : INT; // raw count from Wago
tScale : REAL; // engineering unit, °C
tOffset : REAL; // 4 mA trim, default 0.0
tSpan : REAL; // 20 mA span in °C, e.g. 600.0
END_VAR
BEGIN
NETWORK 1 // Read raw
L PIW 176; // 0..27648 for 0..20 mA
T #tRaw;
NETWORK 2 // Convert INT to REAL
L #tRaw;
ITD; // INT → DINT
DTR; // DINT → REAL
T #tScale;
NETWORK 3 // Linear scale (0..27648 → 0..tSpan °C)
L #tSpan; // 600.0
L #tScale; // 0..27648.0
*R;
L 2.764800e+004;
/R;
T #tScale;
NETWORK 4 // Add offset (4 mA lift if needed)
L #tOffset;
L #tScale;
+R;
T #tScale;
NETWORK 5 // Force positive (ABS)
L #tScale;
ABS;
T #tScale;
NETWORK 6 // Hand to SCADA DB
L #tScale;
T DB24.DBD16;
END_FUNCTION
Network 2 — SCL alternative (single block, type-safe)
// SCL equivalent of FC200
IF bEnable THEN
// 0..27648 → 0..600.0 °C, signed ABS protect
DB24.DBD16 := ABS( DINT_TO_REAL( WORD_TO_INT( PIW176 ) ) * 6.000e+002 / 2.764800e+004 );
END_IF;
WORD_TO_INT? PIW is a WORD (unsigned). STEP 7 STL loads it as 16 bits but monitors it as INT. To stop the +127 → negative artefact, cast to a real explicitly using ITD + DTR, or in SCL DINT_TO_REAL(WORD_TO_INT(...)). This keeps the high bit from being treated as a sign when downstream math crosses the 0x8000 boundary.DB24 layout (extract)
DATA_BLOCK DB 24
STRUCT
dwStatus : DWORD; // byte 0..3
rPV1 : REAL; // byte 4..7 DBD 4
rPV2 : REAL; // byte 8..11 DBD 8
rPV3 : REAL; // byte 12..15 DBD 12
rPV4 : REAL; // byte 16..19 DBD 16 <-- SCADA reads this
rPV5 : REAL; // byte 20..23 DBD 20
END_STRUCT;
END_DATA_BLOCK
If DBD 16 is the SCADA tag, make absolutely sure that bytes 16-19 of DB24 are not re-used by another variable in the same STRUCT. STEP 7 will silently overlap symbols and corrupt the REAL value.
Resolving the Negative-Value Issue at +127 Decimal
The +127 → negative symptom is the result of one of three conditions. Diagnose in this order:
| # | Suspect | Test | Fix |
|---|---|---|---|
| 1 | Wago 750-474 channel 0 configured for 0-10 V (not 4-20 mA) and the loop is over-driving the input. | Force 12 mA into the channel and read PIW 176; if value > 27648 you are out of range. |
Reconfigure channel 0 to 4-20 mA in I/O CHECK / Wago-Conf. |
| 2 | STEP 7 status display of PIW uses DEC (signed); the underlying WORD is correct but the HMI shows sign-flip because of a separate scaling bug downstream. | Open DB24.DBD16 in binary and confirm the sign bit (bit 31) — if it flips at +127, the bug is in the scaling block, not the PIW. |
Insert the explicit ABS shown in FC200 Network 5. |
| 3 | The original FC does L PIW 176 / ITD / DTR / *R scale but the scale constant is negative. |
Online → open the FC (after unlock) → inspect the scaling constant. | Make the constant positive. Use ABS on the result as a belt-and-braces measure. |
For a thermocouple that physically cannot read negative temperature in the process (for example, a furnace interior), applying ABS to the scaled REAL is legitimate. For a process where negative readings are valid (for example, a cold-junction box below 0 °C), ABS hides real faults — so prefer fixing the scaling instead.
Working with Protected FC161 and FC166
STEP 7 know-how protection is a reversible XOR cipher on the block source. To remove it you need:
- The original STEP 7 project file (S7 file format
.s7p) opened in the version that originally compiled it (typically STEP 7 V5.5 / V5.6 for S7-300). - Knowledge of the protection password — without it you cannot recover the body by decryption.
- If the password is lost, the source cannot be recovered. The block will still execute but cannot be edited.
If the password is available:
- In SIMATIC Manager, right-click
FC161→ Object Properties → Know-how protection. - Click Remove protection, enter the password.
- The block recompiles to plain STL.
- Save the project, export STL, and audit segment 12 (the only place that writes to
DB24).
If the password is not available, do not attempt to brute-force the protection — instead, leave FC161/FC166 in service and bolt a new FC200 alongside. The new FC is the only owner of DB24.DBD16; remove any redundant write in the protected block by re-mapping its source pointer to a scratch DB (for example, DB200.DBD16) before re-compiling.
Indirect Addressing DB26 to DB24
The source case mentions an indirect copy from DB26.DBDxx to DB24.DBDxx that does not seem to put DB26.DBD16 into DB24.DBD16. This pattern is typical of an array-indexed PV buffer (for example, 16 channels) that is bulk-copied by an indexed loop.
STL snippet — indexed copy via AR1 / AR2
NETWORK 1
TITLE = 'Indexed copy DB26[i] → DB24[i]'
L 0;
T #iLoop; // iLoop := 0
LOOP: L #iLoop;
L 16; // 16 channels
>I;
JC DONE; // exit if iLoop >= 16
L #iLoop;
SLD 3; // *8 (REAL = 8 bytes per element)
LAR1 ; // AR1 := byte offset in DB26
L #iLoop;
SLD 3;
LAR2 ; // AR2 := byte offset in DB24
OPN DB26;
L DBD [AR1,P#0.0]; // source REAL
OPN DB24;
T DBD [AR2,P#0.0]; // dest REAL
L #iLoop;
+ 1;
T #iLoop;
JU LOOP;
DONE: NOP 0;
SLD 3 multiplies the integer index by 8 because each REAL occupies 8 bytes. If the source array is actually an array of DINT (4 bytes), use SLD 2 instead. Mismatched strides are the single most common reason an indexed copy "works for most words but not DBD 16".Verify the indirect copy by:
- Setting a breakpoint on the loop after
L DBD [AR1,P#0.0]. - Online-watch
AR1,DB26.DBD[AR1],AR2,DB24.DBD[AR2]. - Confirm that when
iLoop = 2(third element, zero-based),AR1 = P#16.0andAR2 = P#16.0. If AR1 or AR2 is off by one element, the loop is reading the wrong source/dest pair.
InTouch Wonderware SCADA Integration
InTouch reads DB24.DBD16 as a 32-bit REAL. The two most common access paths in a legacy SIMATIC/Profibus plant are:
| Path | Driver | Access name example | Item name example |
|---|---|---|---|
| Native Profibus via Siemens CP (older plants) | DASSIDirect | SIEMENS_PROFIBUS | DB24,DD16,F (Float, 4 bytes) |
| Ethernet-MPI gateway (PC with CP5611 + S7 OPC) | OPC Link | S7_OPC | S7:[S7-300]DB24,REAL16 |
| Direct Ethernet to S7-300 PN port (not applicable to pure DP without CP343) | DASTCP / DASSiDirect over TCP | S7_ETHERNET | DB24.DBD16 |
In every path the access item format is the same:
-
Database:
DB24 -
Offset:
16bytes -
Data type:
REAL(4 bytes, IEEE 754 little-endian)
If InTouch shows 0.0 persistently, the most likely cause is not the SCADA tag but the S7 program not writing the DB. Confirm by online-monitoring DB24.DBD16 in STEP 7 — if it is always 0.0 there too, the SCADA is innocent.
If InTouch shows a flickering or noisy value, enable the Deadband and Min/Max Engineering attributes on the tag to suppress jitter below the thermocouple resolution (typically 0.1 °C).
Verification, Commissioning, and Fault Matrix
Commissioning checklist
- Open HW Config and confirm Wago slave address (e.g., 7) and slot 1 = 750-474 starting at PIW 176.
- Online → monitor
PIW 176; force the loop to 4 mA, 12 mA, 20 mA and verify PIW is in the expected band (typically 0, ~13824, 27648 for 4-20 mA). - Online → monitor
DB24.DBD16; verify it tracks the engineering unit (e.g., 0.0, 300.0, 600.0 °C). - Online → monitor the SCADA tag; verify it tracks
DB24.DBD16to within ±0.1 °C. - Power-cycle the station and re-verify — InTouch cache and STEP 7 retentive flags can mask wiring faults during warm restart.
- Run CPU Information → Scan for Diagnostic Events; capture any SF / BF diagnostic buffer entries.
Diagnostic matrix
| Observed | Likely cause | Fix |
|---|---|---|
BF LED on CPU is solid red |
Wago Profibus slave not reachable, wrong address, terminated | Check DP address, terminate both ends with 220 Ω, verify baud rate |
PIW 176 reads 0 but loop has current |
Channel configured for voltage instead of current | Reconfigure 750-474 channel 0 to 4-20 mA in Wago-Conf |
PIW 176 OK, DB24.DBD16 = 0 |
No FC writes to DBD 16 (this case) | Insert FC200 above |
| SCADA shows negative above +127 | Signed-int wrap or scaling sign error | Cast through ITD/DTR and apply ABS
|
| SCADA shows correct value but flickers | OB1 too fast, no deadband | Move scaling to OB35 (100 ms), add deadband in InTouch tag |
| SCADA shows stale value from yesterday | DB24 not in retentive area after power-cycle | Mark DB24 as retentive in CPU properties or load defaults |
| FC161/FC166 body hidden | Know-how protection | Insert FC200 alongside; do not overwrite protected block |
DB26.DBD16 never lands in DB24.DBD16
|
Indexed loop uses wrong stride | Use SLD 3 for REAL (8-byte) stride |
FAQ
Why does my S7-300 PIW 176 value from a Wago 750-474 go negative above +127?
The raw WORD from the Wago coupler is unsigned, but STEP 7's monitor view and downstream STL code often treat it as signed INT. When the high bit of the WORD is set, the value flips sign. Force a clean cast to REAL via ITD + DTR (or WORD_TO_INT in SCL) before scaling, and apply ABS if the process cannot produce negative temperatures.
Where do I find the Function Block that moves PIW 176 into DB24.DBD16 on a CPU 317-2DP?
Search every FC/FB in the program for the symbol DB24 or absolute address DBD 16. With STEP 7, right-click the Blocks container → Reference Data → Display and filter on DB24. Segment 12 of FC161 is the most likely culprit in this layout. If FC161/FC166 are know-how protected and the password is lost, do not try to break the cipher; add a new FC (for example FC200) that owns the transfer and leave the protected blocks in place.
What is the part number for the CPU 317-2DP referenced in this case?
The CPU is the Siemens 6ES7317-2AK14-0AB0. It is a CPU 317-2DP with 1 MB code / 2 MB data work memory, MPI plus two Profibus-DP master/slave interfaces, and dual BF / BF1 / BF2 bus-fault LED groups. Refer to the official SIMATIC S7-300 CPU 317-2 DP manual on Siemens Industry Online Support for the full pin-out and diagnostic-LED map.
How is PIW 176 mapped on a Wago 750-474 over Profibus-DP to a CPU 317-2DP?
The Wago 750-333 (or 750-303) coupler is a Profibus-DP slave. The 750-474 four-channel analog input module occupies slots in the coupler and reports its PIW start address as defined in STEP 7 HW Config. With a 4-channel module starting at PIW 176, channel 0 = PIW 176, channel 1 = PIW 178, channel 2 = PIW 180, channel 3 = PIW 182. Each channel is a 16-bit INT (0 to 27648 for the Siemens 4-20 mA normalization, or 0 to 32767 for the Wago native count).
Can InTouch Wonderware read DB24.DBD16 directly over Profibus without an OPC server?
Yes — using DASSIDirect with a CP5611 or equivalent Profibus card on the SCADA PC, InTouch can access the S7-300 data block directly. The access-name item is typically configured as DB24, offset 16, type REAL (4 bytes, IEEE 754 little-endian). Alternatively, an S7 OPC server (for example, the Siemens Simatic NET OPC server or a third-party server) bridges the data and InTouch consumes it via OPC Link.