"Which software converts ladder to SCL?" is the wrong question, and not because the tools are bad. It's because three completely different classes of tool get filed under one name, and their failure modes have almost nothing in common. Comparing them on "accuracy" is comparing nothing.
Here they are.
1. The three classes
| Class | How it works | What it actually reads | Ceiling | Where it fails |
|---|---|---|---|---|
| Built into TIA Portal | LAD ↔ FBD, LAD → STL | The blocks in your project | Cannot produce SCL — only FBD/STL | Not SCL. STL is assembler-ish: it runs, but nobody can review it, and diffs show nothing semantic |
| In-project add-in | Reads LAD blocks out of the project via TIA Openness / SimaticML, emits SCL source | The project itself — interfaces, tag tables, instance DBs, network order, every part and every wire | Whole-project coverage; anything its rules cannot handle must be surfaced as "review required" | Semantic structures its rule set does not cover (edge memory bits, jumps, MCR, multiple coils) — the answer must be "flag it", never "guess" |
| Screenshot / paste-a-text converters | Paste an image or a text blob, get code back | Pixels or characters — no tags, no instances, no network order | One small network; demos and learning | The information was lost on the input side. This is where "error rate is huge" comes from |
So the widely repeated claim that third-party converters are inaccurate is true of class 3 and false of class 2. Class 2 and class 1 read the same data — the only difference is who generates the SCL.
One more thing to retire: there is no "convert everything in one click". What decides the outcome is not the software; it's the ratio, in your project, between structures that map mechanically and structures that only look like they do.
2. Fourteen structures, judged one by one
The table below is derived from the semantics of the two languages, not from a sample — which is why every row also says how you verify it yourself instead of taking my word for it.
| # | Structure | What conversion can do | Verdict | What you must do |
|---|---|---|---|---|
| 1 | Series/parallel contacts | Boolean expression | ✅ Safe | Check parentheses and operator precedence; don't rely on default associativity |
| 2 | Plain coil | x := expr; |
✅ Safe | Confirm it isn't a multiple coil (row 10) |
| 3 | Set (S) / Reset (R) coil |
IF cond THEN x := TRUE/FALSE; END_IF; |
✅ Converts — inspect the output | When the condition is false the value must hold; an unconditional assignment has already broken the semantics |
| 4 |
RS / SR boxes |
Calls the corresponding FB | ⚠️ Converts, trivially easy to pick the wrong one | They look identical in LAD; the difference only shows when set and reset are true in the same scan. Picking wrong does not error |
| 5 | Positive / negative edge contacts |
R_TRIG / F_TRIG instance, or an explicit last-scan compare |
⚠️ The most commonly broken row | The edge bit must live in static memory. Put it in TEMP and it is rebuilt every scan — the edge disappears, silently |
| 6 |
TON / TOF / TP
|
Calls the IEC timer FB | ⚠️ Converts; instance matters | Instance must sit in STATIC or a multi-instance DB; check PT type/units, and whether "wrapped in an IF" matches the original EN behaviour |
| 7 |
CTU / CTD / CTUD
|
Calls the counter FB | ⚠️ Same as above | Instance location, preset, and the priority of reset vs. load |
| 8 | Multi-instance FB call with parameters | #myFB(IN1 := ..., IN2 := ...); |
⚠️ Converts, parameters get dropped | A missing pin does not error — it just keeps its previous value, so the bug surfaces only in one specific operating case |
| 9 |
JMP / LABEL
|
— | ❌ Cannot convert | SCL has no GOTO. Rewrite the control flow as a CASE state machine or structured branching |
| 10 | Multiple coils (same variable written in several networks) | Sequential assignments | ⚠️ Converts — result depends on order | Make the write order explicit and check whether anything reads between the writes; which write gets read changes everything |
| 11 |
MCR (master control relay) |
— | ❌ Cannot convert | Expand into an explicit condition chain: write out what the outputs do while the zone is disabled |
| 12 |
EN / ENO chain |
EN → IF wrapper |
⚠️ Half converts |
ENO routinely gets dropped → upstream fails, downstream keeps running. Check the return value or error bit explicitly |
| 13 | Implicit type conversion | Explicit conversion functions | ⚠️ Converts — the boundaries move | Re-check divide-by-zero, integer overflow, REAL precision, TIME and counter type limits |
| 14 | Initialisation / first scan (OB100) | — | ❌ Must be manual | Start-up block, static initial values, first-scan behaviour. These only fail after a power cycle |
The pattern is easy to state: connection structure converts; state and timing do not. Rows 5, 6, 8 and 12 are all "the picture carried this for you, and the text won't".
And none of the fourteen will produce a compile error. Which is the real reason "it compiles" proves nothing about a LAD→SCL migration.
3. The brand question, briefly
Search suggestions often put "Siemens" and "Mitsubishi" in the same sentence. There is no universal converter, and there cannot be: the pictures look alike, but three things differ underneath — device addressing (I/Q/M/DB vs X/Y/M/D), instruction set and function-block semantics, and how edges and timers are implemented. A TIA Portal add-in reads TIA Portal projects. Across vendors it's a re-implementation with a fresh I/O mapping, not a conversion.
4. How to verify, without trusting any tool
Three steps, in this order:
- Compare interfaces and tags. IN / OUT / IN_OUT / STATIC / TEMP, one by one; symbol names, types, retentivity. This alone kills most "looks like it runs" illusions.
- Run the same inputs twice. Feed the original LAD block and the new SCL block an identical input sequence, then compare output timing and final values. Minimum coverage: first scan after power-up, start alone, stop alone, both at once, interlock opened mid-run, timer at the threshold, counter at the preset, manual/auto switchover.
- Localise the divergence to a network. The first step where they differ maps back to one row of the table above — then it's either "converted but unchecked" or "should have been rewritten by hand".
Step 2 needs two environments that can run. With TIA Portal and PLCSIM you have them. Without TIA Portal you can still run the SCL side on a cloud simulator that executes scan cycles and returns final values plus PASS/FAIL — I used PLC Cloud Sim for regression runs, and its MCP endpoint lets an agent replay the same case set. To be precise about the boundary: that verifies logical equivalence only. It does not replace PLCSIM timing detail, hardware diagnostics, or commissioning on the machine.
5. So which one
For a real migration, class 2 for the bulk, your own judgement for rows 3–14, and class 3 nowhere near a project. Concretely, the add-in I use is LAD2SCL — a TIA Portal add-in by Hubwiz that reads LAD blocks from the open project and emits SCL. In the interest of not overselling: only the V19 installer has run on a real machine so far; V17/V18/V20/V21 are advertised on the page but have not been verified version by version, and the download buttons for them currently say "not released yet".
The longer Chinese version, with the migration workflow and the pre-release checklist, is here (in Chinese).
The 14-row table is a semantic analysis, not a benchmark. If you find a row that's wrong for your project, that's more useful than a star — tell me which one and what it did.
Top comments (0)