Overview
In Siemens STEP 7 (Classic STEP 7 for S7-300/400 and TIA Portal for S7-1200/1500), Boolean function block (FB) and function (FC) inputs cannot be passed the literal keywords TRUE or FALSE directly when the logic is written in Ladder Diagram (LAD) or Function Block Diagram (FBD). The programmer must instead wire a Boolean tag - a marker bit, a data bit, a local system bit, or a global DB constant - to that input. Statement List (STL) and Structured Control Language (SCL) accept Boolean literals inline because they are text-based languages with direct operand assignment.
This behavior is enforced by the SIMATIC graphical editors. Every terminal on an FB/FC box must be wired to an addressable operand. The compiler checks this rule at the network parse stage, before any code is generated. Typing TRUE or 1 into the input pin of a function box results in either a syntax error or an empty connection flagged as "unwired" during the build. The programmer's only choices are to wire a tag, use a literal in SCL/STL, or refactor the call site.
This reference covers the root cause of the limitation, the documented workarounds using marker bits, local system bits, and global DB constants, the practical FC105 SCALE use case that triggers the question most often, and the TIA Portal / S7-1200/1500 behavior that replaces the Classic STEP 7 pattern. It also documents the equivalent SCL idiom so that the constraint can be lifted whenever the FB/FC is rewritten in SCL.
Why LAD/FBD Reject Inline Boolean Literals
The LAD and FBD editors in STEP 7 are graphical network editors. Each network contains boxes (coils, contacts, FB/FC calls) connected by lines that represent signal flow. A Boolean input on an FB/FC call is one of the connection points (pins) on the right or left side of the box. Every pin must terminate on a writable or readable operand:
- An input address (e.g.,
I0.0,IW10) - A marker address (e.g.,
M0.0,MW2) - A local address inside the calling block (e.g.,
L0.0,#tempBool) - A data block address (e.g.,
DB1.DBX0.0,"MyDB".TagName) - A constant symbol resolved to one of the above
The editor does not present a literal "TRUE / FALSE" picker for Boolean pins the way it presents a number picker for INTEGER or REAL pins. The reason is design consistency: every pin carries the value of the operand it is wired to. A literal is just an unnamed constant, and unnamed constants are not part of the LAD/FBD operand model. The TRUE/FALSE keywords are part of the text-based language definitions (STL, SCL) and the data type declaration grammar, not the graphical network grammar.
STL vs LAD/FBD: Behavior Comparison
STL is a textual assembly-like language. Each statement assigns a value or performs an operation on the accumulator. Because the operand grammar is text, the literal TRUE and FALSE can be passed directly to a Boolean input. The Classic STEP 7 compiler treats them as the constants 1 and 0 of BOOL type.
| Language | Inline Boolean Literal | Tag Required? | Editor Type | Compiler Treatment |
|---|---|---|---|---|
| STL (Statement List) |
TRUE / FALSE allowed |
No | Text | Constant 1 / 0 of BOOL |
| SCL (Structured Control Language) |
TRUE / FALSE allowed |
No | Text | Constant 1 / 0 of BOOL |
| LAD (Ladder) | Not allowed | Yes | Graphical | Error / unwired pin |
| FBD (Function Block Diagram) | Not allowed | Yes | Graphical | Error / unwired pin |
| GRAPH | Not allowed | Yes | Graphical | Error / unwired pin |
Example STL call against FC105 SCALE with the BIPOLAR flag set to TRUE inline:
// STL - FC105 SCALE call with inline TRUE
CALL "SCALE"
IN := MD100
HI_LIM := 1.000000e+002
LO_LIM := 0.000000e+000
BIPOLAR:= TRUE // direct literal accepted in STL
RET_VAL:= MW200
OUT := MD110
The same call in LAD shows the BIPOLAR pin wired to a marker bit M0.0, because the editor refuses to accept the literal text:
// LAD - FC105 SCALE call requires a tag at BIPOLAR
|---[ M0.0 ]---|--- CALL SCALE ---|
IN := MD100
HI_LIM := 1.0e+02
LO_LIM := 0.0e+00
BIPOLAR:= M0.0 // tag required
RET_VAL:= MW200
OUT := MD110
Workaround 1: Marker (M) Bits
The most common workaround is to reserve two marker bytes (or two bits inside an existing marker byte) for static Boolean constants:
| Symbol | Address | Type | Initial Value | Use |
|---|---|---|---|---|
| Always_TRUE | M0.0 |
BOOL | 1 | Hard-wired TRUE constant |
| Always_FALSE | M0.1 |
BOOL | 0 | Hard-wired FALSE constant |
| Never_ON | M0.2 |
BOOL | 0 | Always 0, never written |
| Always_ON | M0.3 |
BOOL | 1 | Always 1, never written |
Three rules apply to these bits:
- Never overwrite them in the user program. Assign them in the symbol table or in startup OB100 once and lock the symbols.
- Document them in the symbol table with comments like "Static TRUE constant - do not overwrite" so the next programmer does not free them up.
-
Reserve a contiguous byte at the end of the M area (e.g.,
MB200throughMB207) so they never collide with scratch flags.
Set the bits in OB100 (warm restart) so the values are loaded after every power-up, even if retentive behavior is not enabled:
// OB100 - initialize constant markers
SET // RLO = 1
S M 0.0 // Always_TRUE := TRUE
R M 0.1 // Always_FALSE := FALSE
S M 0.3 // Always_ON := TRUE
R M 0.2 // Never_ON := FALSE
BE
Workaround 2: Local System (L) Bits
The Classic STEP 7 system firmware supplies free-running Boolean constants in the local data of OB1 (the cyclic main). These bits are declared in the OB1 start information and can be read but should not be written. The relevant ones are documented in the S7-300/400 System and Standard Functions Reference Manual:
| Local Address | Meaning | Typical Use as Constant |
|---|---|---|
L0.0 |
Always 1 (set every OB1 cycle) | Static TRUE |
L0.1 |
Always 0 | Static FALSE |
L0.2 |
Always 1 | Static TRUE (alternate) |
L0.3 |
Always 0 | Static FALSE (alternate) |
L0.4 |
1 on first scan after warm restart, then 0 | Edge of restart |
L0.5 |
1 on first scan after cold restart, then 0 | Edge of cold restart |
L0.6 |
1 on first scan after hot restart, then 0 | Edge of hot restart |
L0.7 |
Reserved | Do not use |
L0.0 and L0.1 are the canonical "always TRUE / always FALSE" taps that ship with OB1. Wire them directly to any Boolean FC input that needs a constant:
// LAD - wire L0.0 to BIPOLAR for unipolar scaling
|---[ L0.1 ]---|--- CALL SCALE ---|
IN := MD100
HI_LIM := 1.0e+02
LO_LIM := 0.0e+00
BIPOLAR:= L0.1 // always FALSE = unipolar
RET_VAL:= MW200
OUT := MD110
L stack is local to the executing block. L0.0 only behaves as a constant inside OB1. Inside any FC/FB the local stack is fresh and starts at zero. Do not reference L0.0 from inside an FC; it will read whatever the calling OB last put there. Always read it from OB1 and pass it down through an IN/OUT parameter, or wire it from a marker byte.For FB blocks instantiated with instance DBs, the equivalent pattern is to declare two STAT variables in the FB and initialize them once in the startup section:
// FB declaration section (Classic STEP 7)
VAR
CONST_TRUE : BOOL := TRUE; // never re-assigned
CONST_FALSE : BOOL := FALSE;
END_VAR
BEGIN
NETWORK 1
A #CONST_TRUE; // wire to FC BOOL input
= BIPOLAR_flag;
Workaround 3: Global DB Boolean Constants
For larger projects, a dedicated Constants DB with named Boolean tags is the most maintainable approach. Each tag carries a comment and is referenced by name across the entire program, eliminating the magic-number problem of "what is M0.0 again?".
// DB100 "Project_Constants" - static Boolean tags
DATA_BLOCK "Project_Constants"
VERSION : 1.0
STRUCT
ENABLE_BIPOLAR : BOOL := FALSE; // comment: SCALE mode flag
USE_HW_LIMITS : BOOL := TRUE; // comment: axis HW limits
INVERT_DIR : BOOL := FALSE;
TEST_MODE : BOOL := FALSE; // comment: cleared at startup
END_STRUCT;
END_DATA_BLOCK
Reference the constant by its symbolic name in the LAD/FBD box:
|---[ "Project_Constants".ENABLE_BIPOLAR ]--- CALL SCALE ---
Three rules apply:
- Mark the Constants DB as non-retentive and write-protected in the hardware configuration so a programming mistake in the field cannot flip the values.
- Use meaningful names (
ENABLE_BIPOLAR, notBit_3) so the call site is self-documenting. - Add a Never re-assign comment to every BOOL tag in the DB; review this rule in every code review.
FC105 SCALE: A Worked Example
FC105 SCALE is the standard function block in Classic STEP 7 that converts a raw analog input (INT 0..27648 or -27648..27648) to a user engineering range (REAL). The BIPOLAR Boolean input selects the input interpretation:
| BIPOLAR | Input Range | Typical Use |
|---|---|---|
| FALSE (0) | 0 to 27648 | 4-20 mA unipolar, 0-10 V unipolar |
| TRUE (1) | -27648 to 27648 | ±10 V bipolar, ±20 mA bipolar |
The BIPOLAR pin must be wired to a Boolean operand. The cleanest pattern is a DB constant:
// LAD network 5: scale analog input AI0 (IW512) to 0..100 percent
NETWORK 5
CALL "SCALE"
IN := IW512 // raw input from AI8x12Bit
HI_LIM := 1.0e+02 // 100 %
LO_LIM := 0.0e+00 // 0 %
BIPOLAR := "Project_Constants".USE_UNIPOLAR_MODE
RET_VAL := MW300
OUT := MD310 // scaled REAL result
If the project uses unipolar sensors exclusively, you can hard-wire L0.1 (always FALSE) to the BIPOLAR pin and skip the DB constant altogether. For mixed-polarity panels where some channels are bipolar and others unipolar, a per-channel DB constant is required because the constant differs per call site.
TIA Portal and S7-1200/1500 Behavior
In TIA Portal (V13 onward), the LAD and FBD editors retain the same constraint: every BOOL input of an FB/FC call must be wired to a tag or to a local variable. The literal keywords TRUE / FALSE are accepted only in SCL and in the textual STL view (S7-1500 only - S7-1200 dropped STL starting with TIA Portal V14). The TIA Portal V20 documentation for S7-1500T axis functions confirms that Boolean tags remain the standard interconnection mechanism for HW limit switches and similar hardware-feature flags:
Interconnecting inputs for HW limit switches with Boolean tags (S7-1500 / S7-1500T, TIA Portal V20)
The TIA Portal implementation patterns are identical to Classic STEP 7 but use the optimized block architecture:
-
Global DBs with retentivity off: create a "Constants" DB containing
TRUE_CONST : BOOL := TRUE;andFALSE_CONST : BOOL := FALSE;. Tag-based access is faster than symbolic access in optimized blocks. -
Instance DB STATs: declare
CONST_TRUEandCONST_FALSEin the FB declaration with default initializers. Read-only by convention. -
Local tags in OB1: the
Tempsection of OB1 is writable by OB1 only and starts cleared; declare aStaticBool_True : BOOL;with an initializer in OB1's startup section (OB100 equivalent) and use it from any FC called by OB1. -
SCL alternative: if the FC/FB is written in SCL, inline
TRUE/FALSEworks at any call site.
The know-how protected blocks in TIA Portal also accept the same constant patterns, but the protection hides the bit mapping from the field engineer; using named tags in a non-protected Constants DB keeps the project readable.
SCL and the Boolean Literal Workaround
When the call site is in SCL, the constraint disappears. SCL is text-based and treats Boolean literals as first-class operands. The following two SCL blocks are equivalent to the LAD workarounds above:
// SCL - inline TRUE/FALSE at FC call
IF "Project_Constants".USE_UNIPOLAR_MODE THEN
// unipolar scale
"Scale_DB"(IN := "Raw_AI0",
HI_LIM := 100.0,
LO_LIM := 0.0,
BIPOLAR := FALSE, // inline literal
RET_VAL => "Err_AI0",
OUT => "Pct_AI0");
END_IF;
// SCL - using local constants
CONST
cTRUE : BOOL := TRUE;
cFALSE : BOOL := FALSE;
END_CONST
"Scale_DB"(IN := "Raw_AI0",
HI_LIM := 100.0,
LO_LIM := 0.0,
BIPOLAR := cFALSE,
RET_VAL => "Err_AI0",
OUT => "Pct_AI0");
The CONST block in SCL is a block-level constant. Inside an FB the same pattern is the static constant declared with the CONST keyword in the FB declaration. SCL constants are evaluated at compile time and consume no instance memory, making them the most efficient of all the workarounds.
Best Practices and Coding Standards
- Always wire Boolean FC inputs. An unwired pin reads the default (0/FALSE) and silently mis-configures the block. Treat unwired Boolean pins as a code-review defect.
-
Centralize constants in a single Constants DB. One DB per project, named
Project_Constants, holding all BOOL, INT, REAL, TIME, and STRING constants. Mark the DB non-retentive and write-protected. -
Use named tags, not raw addresses.
"Project_Constants".ENABLE_BIPOLARis self-documenting;M0.0is not. Symbol-table discipline eliminates most "what does this bit do?" debugging. -
Reserve marker bytes for static constants in legacy Classic STEP 7 only when a Constants DB is unavailable (e.g., migration project without DB rewrites). Use
M0.0/M0.1and document the convention in the symbol table. -
Never re-assign constant tags in the user program. A
SET/Ror a MOVE into a constant tag is a defect. Code-review checklists should flag any write to a tag whose name starts withC_or contains the wordCONST. - Prefer SCL for blocks that need many Boolean constants. The inline literal eliminates the wiring boilerplate and the constant DB entirely.
- Document the convention in the project README: which DB holds the constants, which marker bits are static, and the naming convention. New engineers onboard faster.
Verification and Troubleshooting Matrix
After applying any of the workarounds, run the following verification checks before downloading to the PLC. Each row maps a failure mode to its root cause and the corrective action.
| Symptom | Observed Behavior | Root Cause | Corrective Action |
|---|---|---|---|
| Compiler warning: "No assignment for parameter BIPOLAR" | FC105 builds but pin is unwired | LAD/FBD rejects literal | Wire M-bit, L-bit, or DB constant to the pin |
| SCALE output saturates at 100 % for bipolar sensor | Reading clipped to unipolar range | BIPOLAR pin read as FALSE because unwired | Wire the DB constant ENABLE_BIPOLAR := TRUE
|
| M0.0 reads as FALSE despite being "set" in OB100 | Bit overwritten in cyclic code | Another network resets or moves the bit | Cross-reference search for the M0.0 address; remove the write |
| L0.0 behaves as constant inside FC but not inside FB | Reading from inside FB returns 0 | Local stack is fresh inside FC/FB | Read L0.0 in OB1, pass it via IN/OUT, or use a marker bit |
| DB constant changes after STOP/RUN | Value reverts to default | DB is retentive, OB100 not executed | Either uncheck retentive bit in DB properties or move initialization to OB100 |
SCL call rejects TRUE literal |
Compile error in SCL | Block is LAD/FBD only or call site is in a LAD network | Convert the call site to SCL or wire a tag |
| Constants DB is overwritten by HMI | Values toggle unexpectedly | HMI tag points at the Constants DB | Remove HMI tag connection; mark DB as not visible to HMI |
Online verification sequence after download:
- Open the call site in the LAD/FBD editor. Right-click the BIPOLAR pin and select Monitor/Modify. Confirm the pin shows the expected constant value (TRUE or FALSE).
- Open the Constants DB online and inspect each tag. The Monitor value column must match the declared initial value.
- Force the input sensor (or simulate it via a watch table) and verify the SCALE output spans the engineering range end-to-end.
- Cycle power on the PLC and re-verify. If the constants change after power-up, the DB is not properly initialized in OB100.
FAQ
Why does LAD refuse TRUE/FALSE but STL accepts them?
LAD and FBD are graphical network editors that wire every pin to an addressable operand; the parser has no provision for an inline literal. STL and SCL are text-based languages with a textual operand grammar, so the keywords TRUE and FALSE are valid tokens in any operand position including FC input pins.
What is the simplest one-bit constant I can wire to a Boolean FC input?
Use marker bit M0.0 (TRUE) or M0.1 (FALSE), initialized once in OB100 and never reassigned. For OB1-only networks, L0.0 and L0.1 are read-only system constants that require no initialization.
Will leaving the BIPOLAR pin of FC105 unwired default to TRUE?
No. An unwired Boolean input on a Siemens FC defaults to 0 (FALSE), which forces FC105 into unipolar mode. Bipolar sensors will saturate at the unipolar high range. Always wire the pin explicitly to a tag or a constant.
How do I pass a Boolean constant to a multi-instance FB inside another FB?
Declare a STAT constant in the parent FB with CONST_TRUE : BOOL := TRUE; and wire the multi-instance pin from #CONST_TRUE. SCL supports this directly with the CONST block, which compiles to a true compile-time constant.
Does TIA Portal V20 still forbid inline Boolean literals in LAD/FBD?
Yes. The TIA Portal V20 documentation for S7-1500/S7-1500T axis functions confirms that Boolean tags remain the standard interconnection mechanism for HW limit switches and similar hardware features. Inline TRUE/FALSE literals are only available in SCL and (on S7-1500) STL.