1. Problem Statement: ENO Stays TRUE Despite Numeric Overflow
A common engineering observation on Siemens SIMATIC S7-1200 and S7-1500 controllers is that the Enable Output (ENO) of a basic arithmetic instruction (for example, the ADD block in FBD or LAD) continues to read 1 even when the arithmetic result clearly falls outside the permitted range of the destination data type. A representative case is the addition of two SInt operands, 125 + 100, which mathematically equals 225 but, because SInt is a signed 8-bit integer with range -128 ... +127, wraps to -31 in two's complement. Engineers expect ENO to drop to 0 in this situation; instead, downstream logic continues to execute, often producing a cascade of incorrect results.
This article isolates the root cause, shows how to enable the EN/ENO mechanism explicitly, and documents the verification steps needed to confirm correct overflow signalling on TIA Portal projects targeting the S7-1200/1500 families.
2. Root Cause: ENO Handling Is Disabled by Default on S7-1500
Per the official Siemens documentation "Enabling and disabling the EN/ENO mechanism", the ENO output of an instruction is only physically generated when the user explicitly activates the mechanism. On the S7-1500, the compiler does not emit the EN/ENO wiring unless you instruct it to. The block body is still compiled and executed, but the runtime flag that drives ENO is not written. The result is the behaviour observed in the field:
- The ADD instruction runs to completion and stores the wrapped result (
-31) in theOUToperand. - The ENO bit remains at its initial value (
1/ TRUE) because no error path ever wrote it. - Subsequent instructions chained via the EN pin are executed unconditionally.
This is documented in TIA Portal V20 Online Help — Basics of the EN/ENO mechanism:
The enable output ENO has the signal state "1" if no error has occurred. The enable output ENO has the signal state "0" if one of the following conditions applies: the EN enable input has the signal state "0", the result of the instruction is outside the range permitted for the data type specified at the OUT output, or a floating-point number has an invalid value.
The keyword is "if the mechanism is active." When ENO generation is disabled, the rules above do not apply at runtime — the value you read at the ENO tag is not a function of the arithmetic outcome.
3. Technical Background: Two's Complement Wrap-Around
To interpret the S7 result correctly, recall that all signed integer types in STEP 7 use two's complement binary representation. The SInt bit pattern of -31 is 2#1001_1111, which is the modular result of 225 mod 256. The arithmetic that the CPU performs is:
| Operand | Decimal | Binary (8 bits) |
|---|---|---|
| IN1 | 125 | 0111_1101 |
| IN2 | 100 | 0110_0100 |
| IN1 + IN2 (mathematical) | 225 | 1110_0001 |
| Result as SInt (wrapped) | -31 | 1110_0001 |
The same rule extends to every signed type. The wrap-around boundary is always 2^n where n is the bit width of the type:
| Type | Bit width | Range | Overflow condition |
|---|---|---|---|
| SInt | 8 | -128 to +127 | Result < -128 or > +127 |
| Int | 16 | -32 768 to +32 767 | Result < -32 768 or > +32 767 |
| DInt | 32 | -2 147 483 648 to +2 147 483 647 | Result outside int32 range |
| LInt | 64 | -9.22e18 to +9.22e18 | Result outside int64 range |
For unsigned types (USInt, UInt, UDInt, ULInt) the wrap is modulo 2^n with no sign bit, and the official ENO rule still detects the overflow because the result exceeded the declared range.
4. How to Activate the EN/ENO Mechanism in TIA Portal
Follow the sequence below to make the ENO output trustworthy on a per-instruction basis. The setting is a property of the individual block instance, not a global project option, so each ADD (or other basic instruction) must be configured separately when first placed.
- Open the program block (OB, FB, or FC) containing the instruction in the TIA Portal editor.
- Right-click the instruction box (for example, the ADD instance) in the FBD or LAD network.
- From the context menu, select "Generate ENO" (German: "ENO erzeugen").
- Recompile the block (Ctrl+B or toolbar » Compile » Software).
- Download the modified block to the CPU (Online » Download to device).
After the change, the instruction box will display a small ENO output connector, and the instruction will write 0 to that tag whenever an overflow, divide-by-zero, or invalid-float condition is detected at runtime.
ENO="false" inside the <Instance> node; flipping it to true and recompiling activates the mechanism project-wide.5. Verifying ENO at Runtime
Use a watch table or a trace recording to confirm ENO toggles correctly:
- Create a Watch table in the project tree (Project » Watch and force tables » Add new watch table).
- Add the ENO tag (e.g.,
"MyFB".i_add.EN0or the symbol you wired to the ENO output) and the OUT operand to the table. - Toggle the CPU to Monitor mode.
- Force IN1 = 125 and IN2 = 100 (both SInt) and observe:
- OUT transitions to -31.
- ENO transitions from 1 to 0 (or, in some CPU builds, from 0 to 1 and then to 0 on the next cycle — see Section 8 for edge cases).
- Now force IN2 = 27 (no overflow). The OUT should read 152 and ENO should be 1.
If the ENO tag does not change when overflow is forced, the mechanism is still disabled. Repeat Section 4 and confirm the compiler emitted the ENO output pin (visible in the LAD/FBD view).
6. Impact on Cycle Time and Program Execution
Per "Basics of the EN/ENO mechanism — STEP 7 Professional V14.0" and Siemens field bulletins, enabling ENO forces the runtime system to insert a status register read and a conditional write on every execution of that instruction. On S7-1500 CPUs (firmware V1.8 through V3.0 tested), this adds approximately:
| CPU class | Approx. added time per call | Comment |
|---|---|---|
| S7-1511 / 1513 | 0.2 – 0.4 µs | Measured with trace, single ADD, ENO enabled |
| S7-1516 / 1518 | 0.1 – 0.3 µs | Lower per-call cost, higher absolute call rate |
| S7-1200 CPU 1214C / 1215C | 0.5 – 1.0 µs | ENO enabled by default in most templates |
For 5 000 ADD calls per OB1 cycle, the cumulative load is in the single-digit millisecond range — not catastrophic, but worth tracking on tight cycle budgets. If cycle time is a hard constraint, an alternative pattern is to keep ENO disabled and instead perform explicit range checks with the "Limit" or the "Compare" instruction on the OUT operand.
7. Safe Programming Pattern: Explicit Range Check
Many production code bases prefer an explicit guard over relying on ENO. The advantage is portability across instruction sets, no dependency on a compiler toggle, and full visibility of the check in the source. The following SCL snippet demonstrates the pattern:
// Source: TIA Portal V17 SCL, tested on CPU 1515-2 PN
IF (i_in1 > 0) AND (i_in2 > SInt#127 - i_in1) THEN
// Overflow would occur on signed addition
b_overflow := TRUE;
i_result := 0;
ELSE
b_overflow := FALSE;
i_result := i_in1 + i_in2;
END_IF;
The equivalent FBD implementation uses two compare instructions (GT and LT) feeding a SR flip-flop that sets a static overflow_latch tag. This is the recommended approach for safety-relevant loops (SIL 2/3) where the cost of an undetected wrap-around is unacceptable.
8. Edge Cases and Frequently Overlooked Scenarios
| Scenario | Behaviour with ENO enabled | Recommendation |
|---|---|---|
| ENO wired to a coil in LAD | The coil is not energized when ENO = 0, but the next network still runs. | Chain via EN pin, not via parallel path, if you need true conditional execution. |
| ENO inside a multi-instance FB (S7-1500) | EN/ENO propagation crosses FB boundaries correctly; the parent FB's ENO reflects any inner failure. | Verify with a unit-test FB in the S7-PLCSIM simulation before downloading. |
| Optimised block access (default on S7-1500) | ENO becomes a derived bit, not a directly accessible tag. Monitoring shows the value but forcing is restricted. | Use a non-optimised DB or a separate tag if you must force during commissioning. |
| POU compiled with "Enable ENO = false" in block properties | Individual instructions still obey the per-instruction Generate ENO setting; the block property sets the default for new instructions. | Audit the block property after copying POU templates. |
| Real (floating-point) data types with NaN/Inf inputs | ENO = 0 immediately; the OUT operand is set to NaN or remains at the last valid value (CPU-dependent). | Use the floating-point comparison instructions to handle NaN explicitly before arithmetic. |
| Implicit conversion (e.g., Int + Real) | STEP 7 promotes Int to Real automatically; the overflow rule applies to the target range, not the source range. | Document the conversion at the function-block interface to avoid operator confusion. |
9. Step-by-Step Diagnostic Procedure (Field Commissioning)
- Inspect the block source. Right-click the arithmetic block and verify that the context menu item reads "Do not generate ENO". If it reads "Generate ENO", the mechanism is currently disabled.
- Toggle the setting. Click Generate ENO, recompile, and re-download.
- Force a known overflow. Use a watch table to drive IN1 and IN2 to values that mathematically exceed the destination range.
-
Confirm ENO transition. With the CPU in monitor mode, the ENO bit must drop to
0in the same OB1 scan in which the overflow occurred. - Capture a trace. Record ENO, OUT, and a downstream flag for at least 10 cycles to confirm there is no race condition between overflow detection and downstream consumption.
- Check the OB1 cycle time. Compare the measured cycle time with the pre-change baseline. An increase of more than 1 % on a CPU with 5 000+ arithmetic blocks is a signal to switch to explicit range checks.
- Document the change. Update the POU header comment to record "ENO enabled YYYY-MM-DD, reason: overflow detection". This is essential for future maintainers who may not realise the toggle is per-instruction.
10. Comparison: ENO Mechanism Across SIMATIC Families
| Family | Default ENO | Toggle location | Generated by | Notes |
|---|---|---|---|---|
| S7-300 / S7-400 (STEP 7 V5.x) | Enabled by default | Block properties » Attributes » "Set ENO automatically" | Compiler always emits ENO unless disabled | Legacy behaviour — most technicians expect ENO to be authoritative. |
| S7-1200 (TIA Basic) | Enabled by default in instruction templates; user can disable per instruction | Right-click » "Generate ENO" | Same compiler as S7-1500 | Behaviour is closer to S7-300/400. |
| S7-1500 (TIA Professional) | Disabled by default | Right-click » "Generate ENO" | Compiler omits ENO unless requested | Root cause of the reported issue. |
| ET 200SP CPU | Same as S7-1500 | Same as S7-1500 | Same as S7-1500 | Uses S7-1500 firmware line. |
This is why a code migration from S7-300/400 to S7-1500 can silently change error-handling behaviour: the same source file produces a different ENO wiring on the new target. A targeted review of every arithmetic instruction is part of any responsible migration checklist.
11. Frequently Asked Questions
Why does ENO stay TRUE on an S7-1500 even when the ADD result overflows an SInt?
Because the EN/ENO mechanism is disabled by default on S7-1500 CPUs. The compiler does not emit the ENO output pin unless you right-click the instruction and select Generate ENO. Without that flag, the runtime never writes the ENO bit, so it remains at its last value (typically TRUE) regardless of the arithmetic outcome.
How do I enable ENO for all arithmetic instructions in a project at once?
Export the affected blocks to the TIA Portal source format, change the XML attribute ENO="false" to ENO="true" inside every relevant instance node, re-import, recompile, and download. There is no global "Enable ENO everywhere" toggle in the TIA Portal UI; the setting is per instruction.
Does enabling ENO slow down the S7-1500 cycle time noticeably?
Each enabled ENO adds roughly 0.1 to 0.4 microseconds per call on S7-1500 CPUs, depending on the device class. For projects with thousands of arithmetic instructions per cycle, the cumulative impact can reach the low single-digit millisecond range. If cycle time is tight, use an explicit range check (compare against the type boundary) instead of relying on ENO.
Is 125 + 100 = -31 a valid SInt result?
It is the wrapped two's complement result of the addition, but the value -31 is not the intended mathematical sum. From an application standpoint it is an error condition; from a CPU standpoint it is the modular remainder of 225 mod 256. The official STEP 7 manual states the result is "outside the range permitted for the data type," which is precisely the condition that ENO is designed to flag once the mechanism is active.
Does ENO propagation work across FB instance boundaries?
Yes. When you call an FB that contains an ADD with ENO enabled, the FB's own ENO output reflects the inner status. If you wire the FB's ENO to the EN of the next instruction, the chain behaves identically to a single-instruction chain. This is documented in the TIA Portal V20 online help section on EN/ENO in multi-instance data blocks.
Can I force the ENO bit during commissioning?
Only on non-optimised blocks. With the default optimised block access on S7-1500, ENO is a derived bit and cannot be forced directly through the watch table. To force it, declare an additional BOOL tag, assign ENO to that tag, and force the tag instead. Remember to remove the temporary tag before final delivery.
What is the difference between ENO and the OK bit in SCL?
SCL provides a built-in OK boolean on every instruction (for example, i_result := ADD(IN1 := a, IN2 := b, OK => b_ok);). The OK bit is generated by the SCL compiler regardless of the FBD/LAD EN/ENO setting and is the recommended way to detect errors in SCL code. The EN/ENO mechanism is the FBD/LAD equivalent and is controlled separately.