SCL Best Practices: Naming Conventions, Structure, and Comments
SCL programming best practices based on the Siemens Programming Guideline. Covers naming conventions, code structure, REGION keyword, commenting, language selection, and common mistakes to avoid.
SCL Best Practices: Naming Conventions, Structure, and Comments
These best practices are based on the Siemens Programming Guideline for S7-1200/S7-1500 (Document ID 81318674) and the associated Programming Style Guide — the official Siemens recommendations for writing maintainable, portable, high-quality SCL code.
Naming Conventions
Identifier Rules
Siemens recommends lowerCamelCase for all identifiers. The initial letter is lowercase, each new word starts with an uppercase letter, and no separators (underscore, hyphen) are used.
| Recommendation | Example | Avoid |
|---|---|---|
| lowerCamelCase | conveyorSpeed | Conveyor_Speed, CONVEYOR_SPEED |
| Max. 24 characters | motorTempAlarm | motorTemperatureAlarmHighLevel |
| Descriptive names | fillValveOpen | M10_0, a, x1 |
| No abbreviation chains | motorTemp | mTmpAlm |
Prefix Convention (Siemens Style Guide)
| Prefix | Meaning | Example |
|---|---|---|
| (none) | Standard variable | conveyorSpeed |
inst / Inst | Instance (single/multi) | instMotorControl |
stat | Static variable | statLastValue |
temp | Temporary variable | tempCalcResult |
c / C | Constant | cMaxSpeed |
Block Naming
| Block Type | Convention | Example |
|---|---|---|
| FB | Describes the function | FB_MotorControl |
| FC | Describes the calculation | FC_ScaleAnalog |
| DB (global) | Describes the data content | DB_RecipeParameters |
| DB (instance) | Auto-generated or inst prefix | instMotorControl_DB |
| OB | Keep Siemens default names | Main [OB1] |
Code Structure
Use REGION to Structure SCL Blocks (V14+)
REGION in SCL is comparable to a network in LAD/FBD. It creates collapsible sections with descriptive titles:
REGION Motor Control
// Start/stop logic for conveyor motor
IF startButton AND NOT fault THEN
motorRunning := TRUE;
ELSIF stopButton OR fault THEN
motorRunning := FALSE;
END_IF;
END_REGION
REGION Temperature Monitoring
// Scale and check temperature
currentTemp := INT_TO_REAL(rawTemp) * 100.0 / 27648.0;
tempAlarm := currentTemp > cMaxTemp;
END_REGION
Why this matters: When someone opens a 500-line SCL block, REGIONs let them collapse everything and see only the section titles — just like network titles in LAD.
One Function per Block
Each FB or FC should do one thing. If you find yourself writing a block with 10 REGIONs covering unrelated functionality, split it into separate blocks.
| Approach | Recommendation |
|---|---|
| One OB1 with all logic | Split into called FBs/FCs |
| One FB that does everything | Split by machine function |
| Shared utilities (scaling, limits) | Separate FC library |
Use FBs for Stateful Logic, FCs for Stateless
- FB (Function Block): Has an instance DB that retains values between calls. Use for motors, valves, sequences — anything that has a "state."
- FC (Function): No instance DB, no retained values. Use for calculations, conversions, scaling — pure input→output.
Prefer Multi-Instances Over Single-Instances
When an FB contains inner FBs (e.g., timers, counters), declare them as multi-instances in the static section rather than creating separate instance DBs. This keeps all data for one machine function in one DB.
Comments
What to Comment
| Always Comment | Never Comment |
|---|---|
| The purpose of each block (header comment) | Obvious operations (i := i + 1; // increment i) |
| Why a specific value was chosen | Every single line |
| Non-obvious logic or workarounds | Commented-out old code (delete it) |
| Interface parameters (Input/Output purpose) | |
| REGION titles (visible when collapsed) |
Commenting Style
// Single-line comment — use for brief explanations
(* Multi-line comment
Use for block headers or detailed explanations
of complex algorithms *)
Language Rule
The Siemens Style Guide requires: Do not mix languages within a project. If the project language is English, all comments, variable names, and block names must be in English. Mixing English variable names with German comments creates confusion.
Common Mistakes to Avoid
1. Global Variable Access Inside FBs/FCs
The Siemens Guideline states: "Tags are only used locally. Access to global data is not permitted within FCs and FBs." Pass all data through the block interface (Input, Output, InOut) — this makes blocks reusable and testable.
// WRONG: direct access to global DB inside FB
IF "DB_Global".startCommand THEN ...
// RIGHT: pass through interface
// Block interface: Input startCommand : BOOL
IF #startCommand THEN ...
2. Modifying FOR Loop Counters
The Siemens Guideline explicitly forbids modifying the loop counter inside a FOR loop body. The behavior is undefined and varies between CPU types.
// WRONG: modifying loop counter
FOR i := 0 TO 10 DO
IF condition THEN i := i + 2; END_IF; // UNDEFINED behavior
END_FOR;
// RIGHT: use WHILE if you need variable stepping
i := 0;
WHILE i <= 10 DO
IF condition THEN i := i + 3;
ELSE i := i + 1;
END_IF;
END_WHILE;
3. Using Bit Markers (M) Instead of Global DBs
On S7-1500, global data blocks with optimized access are faster and safer than bit markers. Markers (M) have overlapping byte/word/double-word access — MW 10 overwrites MB 10 and MB 11. Global DB variables are independent.
4. Hardcoded Values
Replace magic numbers with named constants:
// WRONG
IF temperature > 85.0 THEN alarm := TRUE; END_IF;
// RIGHT
IF temperature > cAlarmTempHigh THEN alarm := TRUE; END_IF;
Which Language for Which Task?
| Task | Recommended Language | Reason |
|---|---|---|
| Standard blocks, calculations | SCL | Best readability, no performance disadvantage |
| Binary logic, simple interlocks | LAD or FBD | Easier online diagnosis |
| Call environments (OB1 structure) | LAD or FBD | Visual block interconnection |
| Sequential processes | GRAPH | Purpose-built for step sequences |
| Legacy compatibility (S7-300/400 only) | STL/AWL | Only when required |
The Siemens Style Guide states: "The preferred programming language for standard blocks is SCL. It provides the most compact form and best readability of all programming languages."
Let PLCcheck Pro Check Your Code Quality
PLCcheck Pro identifies naming inconsistencies, dead code, missing comments, hardcoded values, and global variable access inside blocks — automatically.
Upload your code for quality analysis →
Part of the SCL Reference. Based on Siemens Programming Guideline (81318674). Maintained by PLCcheck.ai. Not affiliated with Siemens AG.
Related Articles
S7-300 to S7-1500 Migration: Complete Guide
Step-by-step guide for migrating Siemens S7-300 PLC programs to S7-1500 using TIA Portal. Covers hardware mapping, software migration wizard, optimized data blocks, AWL→SCL conversion, and common pitfalls.
15 min read
migration-guideSTL/AWL Deprecation in S7-1500: Why You Must Convert to SCL
Why AWL/STL runs only in emulation mode on S7-1500, what that means for performance and maintainability, and how to convert your STL code to SCL. Includes conversion strategy and code examples.
10 min read
migration-guideS5 to S7 Migration: The Complete Guide (2026)
Step-by-step guide for migrating Siemens S5 PLC programs to S7-1500. Covers AWL→SCL conversion, timer mapping, address translation, and hardware selection.
18 min read
Analyze your PLC code with AI
PLCcheck Pro explains, documents, optimizes, and migrates PLC code — automatically.
Try PLCcheck Pro →Not affiliated with Siemens AG. S5, S7, STEP 5, STEP 7, and TIA Portal are trademarks of Siemens AG.