Overview: What ENO Means in a Siemens FB/FC Call
In STEP 7 and TIA Portal, every Function Block (FB) and Function (FC) call exposes a binary EN (Enable) input and a binary ENO (Enable Output) output. The execution model is straightforward: when EN = 1, the block is invoked; when EN = 0, the block is skipped and ENO is forced to 0. For system blocks delivered by Siemens, ENO is wired by the compiler based on the runtime result of the underlying instruction. For user-written FBs, ENO is not implicit; the engineer must assign it explicitly. This is the single most common reason a user FB returns ENO = 0 with no diagnostic entry and no apparent internal error.
Why the Diagnostic Buffer Stays Empty
The S7-300, S7-400, S7-1200, and S7-1500 diagnostic buffer records only a defined set of events: CPU stop / run transitions, OB121 programming errors, OB122 I/O access errors, module pull/plug, rack faults, and a limited number of system-level warnings. A user FB that completes execution with a logically wrong result, an unassigned ENO, or a chain of failed sub-block calls does not raise any of these events. The CPU has no semantic way to know that ENO = 0 is "wrong" vs. "intentional."
Consequence: if your only signal of a problem is ENO = 0 at a call site, the diagnostic buffer is the wrong tool. Use online monitoring, watch tables, single-step STL execution, and breakpoints in the FB instead.
The EN / ENO / BR / OV / OS Signal Chain
ENO is one link in a broader signal chain that engineers often confuse. The table below lists every bit that influences - or is influenced by - a block call's enable path.
| Bit | Location | Set / Cleared By | Typical Use |
|---|---|---|---|
| EN | Call box input | Power flow into the call in LAD/FBD; argument in SCL | Skip the block when condition is false |
| ENO | Call box output | Compiler for system blocks; user code for user FBs | Chain to next call or to a coil |
| BR (status word bit 8) | Status word | System FBs/FCs that use the older BR/CC0/CC1 model | Backward compatibility with S7-300/400 FCs |
| OV (status word bit 5) | Status word | Math overflow on the most recent REAL/DINT operation | Detect overflow in a single network |
| OS (status word bit 4) | Status word | Latched overflow until next math operation | Persistent overflow flag across networks |
| CC0 / CC1 | Status word bits 6, 7 | Condition code from the last math/comparison/word op | Result classification (==0, >0, <0, unordered) |
If a math instruction inside the FB triggers an overflow, OV and OS will latch. A downstream check that reads the status word and translates it to ENO can then propagate ENO = 0. Open the Monitor view in TIA Portal and click the status word column to see OV, OS, CC0, and CC1 live.
Step-by-Step Debugging Procedure
The following procedure is the fastest path to a root cause for an FB that returns ENO = 0 with no diagnostic buffer entry. It applies to STEP 7 V5.x, TIA Portal V13 SP1, and later TIA Portal versions.
- Verify EN is 1. In LAD/FBD, EN is the power-flow rail entering the call box. An open contact, a coil with current=0, or a missing assignment upstream will leave EN = 0 and force ENO = 0 regardless of block internals. In SCL, inspect the boolean expression that gates the call.
- Open the FB online. Right-click the FB in the project tree, choose Open in monitor mode (TIA Portal) or Monitor / Modify > Monitor (STEP 7 V5). The editor paints actual values over the static addresses of in/out/inout/static/temp variables.
- Add the FB to a watch table. Drag the instance DB, the ENO flag, and the FB's input/output parameters into a watch table. Force trigger conditions to make the FB execute predictably.
- Set a breakpoint on the last network. In TIA Portal, click in the gray gutter to the left of the network. The runtime halts when execution reaches the network, allowing you to inspect variables in their post-update state.
- Switch to STL single-step mode. STL shows every instruction the compiler emits and lets you step with Debug > Step Over and Debug > Step Into. When a block calls another block, Step Into enters the called block; Step Over executes the call and stops after it. This is the most precise tool for finding the exact instruction that sets ENO = 0.
- Check the ENO of every called FB/FC. If your FB calls a sub-block, the sub-block's ENO is your FB's first chance to inherit a 0. Inspect each call site independently.
- Inspect temp variables. Temp (L stack) memory is not retained between scans. Reading a temp before it is written in the current scan returns the residual value from the last block that used that L-stack slot, which is the classic source of intermittent ENO = 0 on a DIV or SQRT.
- Capture status word bits. Add a temporary tag and assign the status word to it. In TIA Portal, drag the STW (status word) tag of the corresponding OB into the watch table; OV and OS bits are visible at the bit level.
- Use the call hierarchy. Right-click the FB > Call hierarchy shows every call site, the instance DB, and the parameters passed in. A wrong instance DB or a missing instance DB at a call site can present as ENO = 0 at the box even when the FB internals are sound.
- Cross-reference the ENO output. Right-click > Cross-references on the FB call shows every place the FB is invoked. Check each call site for consistent instance DB usage.
Troubleshooting Matrix: Symptom to Root Cause
| Symptom Observed | Most Likely Root Cause | First Check | Standard Fix |
|---|---|---|---|
| ENO = 0 on every call, every scan | ENO never assigned in user FB | Open FB in monitor mode; check last network | Add ENO := ok; in SCL, or wire a coil to ENO in LAD/FBD |
| ENO = 0 only when a specific input value is present | Math overflow or invalid domain (sqrt of negative, log of zero) | Watch OV and OS bits in the status word | Range-check the input before the math op; gate the unsafe path |
| ENO = 0 on the first scan after download / MRES | Temp variable read before written | Inspect all temp variables in the FB on first cycle | Initialize temps or move to static in the instance DB |
| ENO = 0 only when called from one specific OB | Instance DB mismatch or wrong caller parameters | Open call hierarchy for the FB | Correct the instance DB reference at the call site |
| ENO = 0 after a TIA Portal version upgrade | Optimised vs non-optimised block access mismatch | Right-click FB > Properties > Attributes | Align "Optimised block access" flag between FB and instance DB |
| ENO = 0 only inside an HMI or web server function | GET / PUT access on a know-how-protected FB | Remove protection and re-test | Restructure to expose only the necessary tags |
| ENO = 0 after a library update | Library FB recompiled; old instance DB has wrong layout | Recompile and re-download the project | Update the library link and re-download everything |
| ENO = 0 randomly, with no clear pattern | Local temp reused by another block; race with the OB priority class | Reduce temp usage; check OB priority | Convert critical temps to static or global flags |
Common Root Causes of ENO = 0
Based on field experience, ENO = 0 in a user FB with an empty diagnostic buffer falls into one of seven buckets. Each is described with detection cue and the standard fix.
1. ENO Is Never Set in the User FB
Detection: STL single-step shows the network reaches the end of the FB without an instruction that writes to ENO. Watch table on the call box shows ENO = 0 the first scan and every scan thereafter.
Fix (LAD): terminate the FB with a coil wired to a local error flag and assign that flag to the ENO output of the call box at the call site, or wire ENO inside the FB body if the editor permits.
Fix (SCL): add the line ENO := NOT errorFlag; (or ENO := ok;) as the last statement before END_FUNCTION_BLOCK.
Fix (FBD): add an Assign box whose input is the local error flag inverted and whose output is the ENO box pin.
2. ENO Propagated from a Called FB/FC
Detection: Open the called FB in monitor mode; its ENO is already 0. The parent's ENO drops after the call returns.
Fix: Fix the called FB first, then re-verify the parent. If the called FB legitimately must return 0, branch on that result inside the parent and write a meaningful ENO.
3. REAL / LREAL / INT Type Mismatch at the FB Boundary
Detection: FB input pin is declared REAL but the caller passes INT. In monitor mode the FB sees a corrupted value; SQRT, LN, EXP, and scaling functions set ENO = 0. In SCL the compiler warns about implicit conversion; in LAD/FBD the type mismatch is silent unless the call box shows a red tag.
Fix: align pin types with caller types. Convert explicitly with INT_TO_REAL / REAL_TO_INT / DINT_TO_REAL in SCL, or correct the tag type in the variable table.
4. Local Temp Variables Read Before They Are Written
Detection: The FB uses a temp variable for the process value. The first scan of the OB, or the first call after a different FB occupies the same L-stack slot, returns garbage. In monitor mode, the temp displays as undefined (---) or a residual value.
Fix: initialize the temp at the top of the FB, or move it to a static variable in the instance DB if retention across scans is required. Note that static in the instance DB persists for the lifetime of the DB; temp does not.
5. Division by Zero or Invalid Domain Argument
Detection: OV and OS latch. The status word shows CC0/CC1 in the "unordered" combination. The math instruction that triggers it is the line directly above the ENO = 0 observation.
Fix (SCL):
IF divisor <> 0.0 THEN
quotient := dividend / divisor;
ENO := TRUE;
ELSE
quotient := 0.0;
ENO := FALSE;
END_IF;
Fix (LAD): use a comparator to gate the DIV box; pass the result through a MOVE on the safe path and 0.0 on the unsafe path.
6. ENO Cleared by a Comparator or Open Branch
Detection: The last network of the FB contains a comparator whose result is 0, and the network terminates without a coil. TIA Portal V13 / V14 / V15 in some configurations evaluates ENO to the comparator's result instead of holding the prior value.
Fix: add a final Assign box or coil that writes a deterministic value to ENO at the end of every code path.
7. Wrong Instance DB at the Call Site
Detection: Cross-reference shows two call sites; one passes a different instance DB than the one the FB was compiled against. Monitor mode on the FB shows mixed/garbage static data because the static area is sized for a different version of the FB.
Fix: recompile the FB and re-download the project, or correct the instance DB reference at the call site. After firmware updates of TIA Portal, the FB can be re-compiled with a different interface description; only a matching instance DB preserves the static layout.
SCL-Specific Behaviour
SCL (Structured Control Language) treats ENO as a writable boolean in the FB scope. The compiler emits implicit ENO handling only for system-provided FBs and for direct invocations of system functions. For user FBs the engineer must assign ENO at every exit path.
Pattern - safe division with explicit ENO:
FUNCTION_BLOCK FB_SafeDiv
VAR_INPUT
dividend : REAL;
divisor : REAL;
END_VAR
VAR_OUTPUT
quotient : REAL;
END_VAR
VAR
ok : BOOL;
END_VAR
BEGIN
IF divisor <> 0.0 THEN
quotient := dividend / divisor;
ok := TRUE;
ELSE
quotient := 0.0;
ok := FALSE;
END_IF;
ENO := ok;
END_FUNCTION_BLOCK
Pattern - cascading ENO through nested FBs:
tmp_ok := FB_A(EN := TRUE, ...);
IF tmp_ok THEN
tmp_ok := FB_B(EN := tmp_ok, ...);
END_IF;
ENO := tmp_ok;
The isNaN and isInf helpers are available in SCL for S7-1500; on S7-1200 / S7-300 / S7-400 they must be emulated with explicit range checks.
Pattern - NaN guard for S7-1500 SCL:
IF divisor <> 0.0 AND NOT ISNAN(divisor) AND NOT ISINF(divisor) THEN
quotient := dividend / divisor;
ENO := TRUE;
ELSE
quotient := 0.0;
ENO := FALSE;
END_IF;
LAD / FBD / STL / SCL ENO Wiring Comparison
| Editor | ENO Source | Implicit? | Debug Tip |
|---|---|---|---|
| LAD | Power flow into the ENO output of the call box | For system FBs only | Hover the call box for the actual ENO value; click to expand |
| FBD | Boolean output of the box | For system FBs only | Wire ENO to a flag tag and monitor it in a watch table |
| STL | Last instruction that affects the status word | No | Single-step with Debug > Step Over to watch the BR / ENO bit |
| SCL | Writable boolean symbol ENO | No | Assign ENO at every return path; use compiler warnings as a checklist |
Watch Tables and Cross-Reference for Localisation
- Create a Watch table containing: the instance DB of the suspect FB, the global ENO flag (if you have wired one), the input tags, and the output tags of the FB.
- Force the call condition (EN = 1) using Modify in the watch table.
- Trigger the FB in single-scan mode: CPU > Operating Mode > Single Scan in TIA Portal, or the equivalent toolbar button in STEP 7 V5.
- Use Cross-reference (right-click in project tree > Cross-references) on the FB to find every call site; an external call with a missing or wrong instance DB can present as ENO = 0 at the call box even when the FB internals are sound.
- Open the Call hierarchy of the FB (right-click the FB > Call hierarchy) to inspect parameters passed in by callers.
- Use Go to location on the ENO output to navigate to the network that consumes it; a downstream coil assigned from ENO that never energises is a visible symptom.
Status Word and Condition Code Inspection
The status word is a 16-bit register visible in monitor mode at the bottom of the editor. The bit layout relevant to ENO debugging is:
| Bit | Name | Meaning in ENO Debugging |
|---|---|---|
| 0 | CC0 / /ER | Result class bit 0; /ER on FCs older than S7-400 |
| 1 | CC1 / RLO | Result class bit 1 |
| 2 | CC2 / STA | Result class bit 2 |
| 3 | CC3 / OR | Result class bit 3 / OR of status bits |
| 4 | OS | Stored overflow - latched |
| 5 | OV | Overflow on the most recent math op |
| 6 | CC0 (alt) | Condition code bit 0 |
| 7 | CC1 (alt) | Condition code bit 1 |
| 8 | BR | Binary result - legacy FC ENO carrier |
On S7-1200 / S7-1500, the BR bit (bit 8) is reserved for compatibility with S7-300/400 FCs and is set by the runtime when the equivalent ENO would be 1. The newer ENO pin on the call box is the preferred signal; BR is informational.
Local Temp Variable Retention Rules
The L stack (local / temp area) is a finite, sized memory area reserved for the current OB and its call chain. The rules are:
- Temp variables are not initialized by the runtime. Reading before writing in the same scan returns the residual value from the last block that occupied that L-stack slot.
- Temp variables are not retained across scans. A value written by an OB in cycle 1 is undefined in cycle 2.
- Temp variables are not retained across block boundaries. When the OB exits, the L stack is released; when the OB is re-entered, the L stack is re-allocated but not zeroed.
- Temp memory is limited. S7-300 provides 256 bytes per priority class; S7-1200 and S7-1500 provide more but still finite. Excessive temp use causes the compiler to issue a warning and the runtime to overflow into adjacent data.
Implication for ENO debugging: a temp that is read by a comparator or by a math instruction before it is written in the same scan can return 0 (the residual) and propagate ENO = 0 in the calling network. Move the value to a static in the instance DB, or assign a deterministic initial value at the top of the FB.
Compiler Warnings Relevant to ENO Debugging
| Compiler Warning | Meaning | Action |
|---|---|---|
| "Variable not assigned" on ENO | ENO is never written in the FB | Add an explicit ENO assignment at every exit path |
| "Implicit conversion REAL <- INT" | An INT is passed where REAL is expected | Add explicit INT_TO_REAL or change the pin type |
| "Temp variable possibly uninitialized" | A temp is read on at least one path without a prior write | Initialize the temp at the top of the FB or move to static |
| "L stack overflow" | More temp bytes than the priority class allows | Reduce temp usage; check OB priority configuration |
| "Return value not assigned" | The function's return value is never written | Assign the return value or declare the function as VOID |
Cross-Platform Notes: S7-300 vs S7-400 vs S7-1200 vs S7-1500
| CPU Family | ENO Default | BR Bit Usage | Optimised Block Access | Compiler Warning on ENO |
|---|---|---|---|---|
| S7-300 | User must assign; system FBs implicit | Yes, primary mechanism for FC ENO | Not available | No - manual review required |
| S7-400 | User must assign; system FBs implicit | Yes, primary mechanism for FC ENO | Not available | No - manual review required |
| S7-1200 | User must assign; system FBs implicit | Compatibility only | Default on for new projects | Yes, TIA Portal emits a warning |
| S7-1500 | User must assign; system FBs implicit | Compatibility only | Default on for new projects | Yes, TIA Portal emits a warning |
Verification Checklist After the Fix
- ENO = 1 across all expected scan conditions: cold start (OB100), warm restart (OB101), hot restart (OB102 on S7-400), and normal cyclic OB1.
- Watch table shows all instance DB tags at their expected values throughout one full process cycle.
- OV / OS bits in the status word stay 0 during math operations.
- No OB121 / OB122 "Programming error" / "I/O access error" entries in the diagnostic buffer after one full process cycle.
- Single-scan and continuous-run modes produce identical results.
- The call hierarchy shows one consistent instance DB per call site.
- The cross-reference list shows no orphan call sites referencing the FB without a matching instance DB.
- For SCL FBs, the compiler emits no "variable not assigned" warning for ENO.
Commissioning Workflow
- Pre-commissioning: compile the project, resolve all warnings related to ENO / BR / status word.
- Download: perform a full download to the target CPU. Do not skip blocks; a partial download leaves an FB compiled against one instance DB and a different version in the CPU.
- Cold start: perform MRES or power-cycle to clear residual DBs.
- Online attach: open the suspect FB in monitor mode and the corresponding OB1 segment.
- Force inputs: in a watch table, force the inputs to the FB to deterministic values. Toggle the EN bit manually.
- Single-step: switch to STL if the FB is in LAD/FBD. Step through the FB one network at a time, watching ENO after each network.
- Fix and re-verify: apply the change, recompile, re-download, re-verify the checklist above.
Edge Cases and Field-Proven Caveats
- Optimised block access. When the FB is compiled with "optimised block access" (S7-1500 default), the instance DB no longer has a fixed layout; some non-optimised callers can corrupt static values and present as ENO = 0. Match access optimisation between FB and caller.
- Know-how protection. A know-how-protected FB shows only the interface; the body is hidden. You cannot set a breakpoint inside the FB. Diagnose by monitoring interface tags only, or temporarily un-protect the FB.
- Multi-instance FBs. When an FB is called as a multi-instance (static of type FB), each instance has its own static area but they share the parent's instance DB. A wrong "instance" identifier at the call site can be confusing; cross-reference resolves it.
- Library FBs. A library FB that you have not recompiled can fall out of sync with the project if the master copy library is updated. Re-link the library version in the project tree.
- PLC firmware mismatch. TIA Portal versions older than the PLC firmware can compile FBs the runtime does not fully understand. The symptom is intermittent ENO = 0 with no obvious cause. Update TIA Portal or downgrade the PLC firmware to match.
- Indirect call via IN_OUT FB parameter. Passing an FB as an IN_OUT parameter in SCL creates a polymorphic call. The compiler may insert type checks that fail at runtime; the symptom is ENO = 0 at the call box. Avoid this pattern unless the FBs share a common interface.
- Cyclic OB priority. OB1 runs at priority 1 by default. A time-of-day OB (OB10) or a hardware interrupt OB (OB40) can interrupt OB1; if the FB is not re-entrant, the second call corrupts the static of the first. Mark the FB as re-entrant in its properties, or guard the FB instance with a semaphore.
Related Tools and References
- Siemens Industry Online Support - entry point for STEP 7 / TIA Portal manuals and FAQs.
- SIMATIC S7-1200 Programmable Controller System Manual - documents the LAD/FBD/SCL ENO model on S7-1200.
- SIMATIC S7-1500 Automation System System Manual - documents optimised block access, multi-instance FBs, and the ENO model on S7-1500.
- STEP 7 (TIA Portal) Programming and Operating Manual - documents SCL, ENO handling, and the compiler's ENO warnings.
Frequently Asked Questions
Why does my user-written FB always return ENO = 0 even when the logic looks correct?
User-written FBs do not automatically set ENO = 1. Add an explicit ENO assignment as the last action before the block exits: ENO := NOT errorFlag; in SCL, or a coil wired to the ENO output in LAD/FBD. Without that assignment, ENO retains the residual value from the prior instruction in the network, which is frequently 0.
Can a logical programming error produce a diagnostic buffer entry in STEP 7 / TIA Portal?
No. The diagnostic buffer records CPU stop / run transitions, OB121 programming errors, OB122 I/O access errors, and system-level events. A pure logical error or unassigned ENO will not appear there. Use online monitor, watch tables, and STL single-step debugging instead.
What is the difference between ENO and the BR bit in the status word?
On older S7-300 / S7-400 CPUs, the BR (Binary Result) bit of the status word served the role of ENO for FC calls. On S7-1200 / S7-1500 the BR bit is retained for compatibility, but the ENO pin on the call box is the preferred signal. The BR bit is set by the runtime when the equivalent ENO would be 1; you can read it from the status word tag in monitor mode.
My FB uses a local temp variable that loses its value every scan. Is that normal?
Yes. Temp (L stack) memory is not retained between scans and is not initialised by the runtime. If you need persistence, use a static variable in the instance DB or a global flag. A temp that is read before it is written in the same scan returns the residual value from the last block that used that L-stack slot, which is a common source of intermittent ENO = 0.
How do I debug an FB that is called from another FB in TIA Portal V13 SP1 and later?
Set a breakpoint in the called FB, then trigger the parent. TIA Portal halts at the breakpoint, allowing single-step execution through the called FB with full visibility of in / out / inout / static / temp variables. For nested calls, Step Into enters the deeper block; Step Over executes the call and stops after it.
How does ENO behave differently in S7-300 / S7-400 vs S7-1200 / S7-1500?
On S7-300 / S7-400, the BR bit is the primary mechanism by which an FC signals success. The ENO pin exists for LAD/FBD call boxes but is wired through the BR bit. On S7-1200 / S7-1500, ENO is its own boolean and is independent of BR. The compiler on S7-1200 / S7-1500 emits a warning when a user FB never assigns ENO; on S7-300 / S7-400 the warning is not emitted, so manual review is required.
Can a division by zero inside an FB cause ENO = 0 without a diagnostic buffer entry?
Yes. REAL / LREAL division by zero does not raise a CPU-level fault; it sets the OV and OS bits in the status word and propagates a special REAL value. A math FB that inspects OV / OS will write ENO = 0. The diagnostic buffer stays empty because the CPU did not fault. Always guard the divisor before the DIV instruction in SCL or wire a comparator in LAD/FBD.