The missing piece in AI-assisted PLC programming isn't code generation — it's proof. PLC AI 实战 is a free, seven-lesson, text-and-screenshots course that breaks that problem into seven checkable endpoints: a compile with 0 errors and 0 warnings, a read-back that matches the spec, a scenario report that says PASS/FAIL, and a regression run that shows behavior didn't change. No videos, no course upsell, and nothing to download.
I went through all seven lessons and pulled out the parts that matter if you already write PLC code for a living — plus the three failures the course deliberately shows instead of hiding.
1. The bottleneck moved from "write it" to "prove it"
Almost every engineer's first reaction to AI-generated SCL is the same: looks about right, but I don't dare use it.
"Looks about right" comes from the model's strengths — interfaces, variable names, IF/THEN structure. "I don't dare" comes from the plant floor: a wrong PLC program doesn't cost you a compile error, it costs you a machine doing the wrong thing.
The course is valuable because it shows three real failures rather than a demo where the AI gets it right the first time:
-
Compiles clean, spec not implemented. The requirement said "after the sensor triggers, output for 2 seconds." The implementation used
TON. The sensor is only high for one scan cycle, so the timer'sETnever reaches 2000 ms and the output never turns on once. -
Compiles clean, nothing moves. While refactoring a three-motor delayed-start sequence,
TPwas written asTON. Compile: 0 errors, 0 warnings. Press the button: none of the three motors start. -
Compiles clean, the field never reads it. When changing an IO address, the TIA compiler does not check whether a physical channel exists. Point a tag at
I30.0, which this project doesn't have, and you still get 0 errors and 0 warnings.
All three have the same shape: the compiler cannot see them. So the only defensible criterion is: every step needs evidence someone else can re-check — not the agent saying "done."
2. Four layers of verification, and what each one does not prove
This is the table worth remembering. Each lesson tells you which layer you're on:
| Layer | Who judges | Proves | Does not prove |
|---|---|---|---|
Structural validation (scl_validate) |
The cloud simulator's parser | Source parses, structure is legal | TIA compile rules, behavior |
| TIA compile | The TIA Portal compiler | The block compiles in your project (0 errors, 0 warnings) | Behavior matches the spec; the address has a physical channel |
| Cloud simulation | A scan-level simulator | Under a given input sequence, output assertions hold (PASS/FAIL) | Hardware, bus, HMI, safety circuits; also not the TIA compiler |
| Virtual PLC / real hardware | S7-PLCSIM Advanced / the machine | Real scan behavior after download, diagnostics, faults | Safety functions, interlocks, e-stops still need human review |
A practical detail: scl_validate returning ok: true only means the source parses. The timer call from lesson 1 that omits PT will likely pass structural validation, while TIA reports Parameter 'PT' has to be used.
3. How the seven lessons are ordered
| Stage | Lesson | Tool | Time | Endpoint (what you walk away with) |
|---|---|---|---|---|
| Beginner | Write SCL: from requirement to 0 errors, 0 warnings | TiaLink | 30 min | A clean compile plus a requirement → implementation → verdict table |
| Beginner | Modify the first example in the library | TiaLink | 20 min | One added tag, one series contact, clean compile, structural read-back |
| Intermediate | Read an undocumented legacy TIA project | TiaLink (read-only) | 25 min | A project specification document + a human review list; zero changes |
| Intermediate | Change one IO address — what breaks? | TiaLink (read-only + dryRun) | 25 min | Reference list, risk list, change plan, preflight result |
| Intermediate | Simulate before commissioning: download to a virtual PLC | TiaLink + PLCSIM Advanced | 35 min | A scenario table with measured values |
| Intermediate | No TIA install: turn SCL into PASS/FAIL in the cloud | Cloud simulation MCP | 35 min | An ALL PASS report plus the scan count |
| Hands-on | Refactor without changing behavior: 3 copies → 1 FB | TiaLink + PLCSIM | 40 min | Baseline vs regression, point by point |
About 3.5 hours total. The order isn't by topic — it's the order work actually happens: write → modify → read → assess impact → simulate → verify → regress. Every lesson ends with a verification checklist; if you can't tick it, you're not done.
4. The seven things that actually trip people up
4.1 First compile: 2 errors, 2 warnings
The only input is one requirement: an FB_Sorter with Start / SensorA / SensorB / Reset in, DiverterA / DiverterB / Running out, interlocked, 2-second outputs, reset clears everything. Everything after that — read the project, add a CPU, write the block, import, compile, fix, read back, save — is the agent's job.
Measured on TiaLink 1.1.0.0 + TIA Portal V19 + S7-1200 (CPU 1214C, V4.6). The first version reads like it satisfies the spec, and compiles to 2 errors and 2 warnings:
-
[Error] Parameter 'PT' has to be used.— a timer call must supplyPTevery time, including the reset branch. The correct shape is one call per scan with reset folded intoIN. -
[Warning] The parameter '#Running' might not be initialized.— the output is read before it is definitely assigned. Carry the state in a Static variable with an initial value and assign the output unconditionally at the end.
Two engineering disciplines hide here as well: every import leaves behind an external source file in the project (they pile up over iterations), and import ≠ save — a successful import is not a saved project.
4.2 Modifying an example: don't import it into a live project
The second lesson practices the more common job: take existing logic and change it. The simplest library example (a single-button toggle, 4 networks in LAD) gets one new input: Enable at %I0.1, forcing the output off when 0 and preserving the toggle when 1.
Two edits total: one new tag, and one series contact after the power rail in Network 2. After a clean compile, structural read-back confirms Motor = Enable AND (Tag_1 OR Motor) AND NOT Tag_2.
Two genuinely annoying traps:
-
UIdmust be a decimal integer — hex is rejected outright; -
TIA renumbers
UIdafter import, so you cannot assert onUId; assert on structure instead.
And one precondition: examples ship with Main (OB1) and Default tag table, so importing overwrites same-named objects. Get a clean baseline compile first, so that when something breaks later you know whose fault it is.
4.3 Reading a legacy project: separate confirmed / inferred / unconfirmed
The third lesson is read-only against an MIT-licensed sample project: 5 blocks (OB1 + FB2/FB3 + DB12/DB13), 51 tags, 3 HMI screens with 40 variables. The output is a project specification, with zero changes to the project.
Three classic legacy shapes show up immediately:
-
The CPU is an F-type (
1513F-1 PN,6ES7 513-1FL02-0AB0, firmware V2.9) but there are no F-blocks. That doesn't mean the hardware is wrong, but it has to be listed as a safety item for a human to confirm. -
An FB with an empty interface is not an empty block:
Auto_mode/Manu_modehave no parameters at all; the logic reads and writes global variables (ZS-*,CV-*,HMI_*,SIM_*). Which means: track change impact through variables, not through interfaces. -
One giant network:
Auto_modehas a single network with 36 operands; 2 ofMain's 4 networks are empty. Treating that as "one rung" is guaranteed to be wrong — split it into functional segments (sensor chain, actuator chain, alarm/simulation, MATLAB handshake).
One more reconciliation: 6 of the 51 tags are not referenced by any PLC block, and HMI_PID deserves special mention — the HMI has a PID screen, but there is no PID block and the tag is unused. "PID may not be implemented" is a human-confirm item. A document that doesn't distinguish confirmed / inferred / unconfirmed is fiction.
4.4 Change-impact analysis: a clean compile does not mean the field can read it
The fourth lesson answers "can I touch it?" One candidate change: ZS-101 (Infeed Sensor) from %I29.0 to %I29.4. Read-only throughout, with a dryRun preflight at the end.
The result is cleaner than expected — and more dangerous:
-
References: 6 in
Auto_mode+ 2 inManu_mode, all reads, and zero absolute addresses inside blocks. So no block needs editing; only the tag table changes. That's what "impact assessed" means. -
The HMI is symbolic (
AddressAccessMode=Symbolic), so the address change follows automatically — but address strings hard-coded in screens or comments are not visible to the compiler and need a human. -
Hardware mapping:
%I29.0belongs to the ET200SPDI 8x24VDC ST_2(Input29);I29.0–3areZS-101..104, so%I29.4is a free channel on the same module. - The dangerous part: TIA does not validate that the address has a physical channel. Point it at a non-existent address and you still get a clean compile, while the field never sees the signal. Changing an address also means changing the wiring ↔ address mapping — moving a terminal is something only a person or a drawing can confirm.
-
dryRunreturns{action: "overwrite", kind: "tagTable", tagCount: 27}— you thought you changed one line; the whole 27-tag table gets rewritten. Without this preflight, you find out after other tags silently revert.
4.5 Virtual PLC: behavior finally becomes visible
The fifth lesson runs the program: the library example "exhaust fan control" (one network, TOF of 1 minute) is downloaded into an S7-PLCSIM Advanced 6.0 instance, driven by a scenario table, with measured values recorded.
The first whole-project compile is 0 errors, 1 warning: Inputs or outputs are used that do not exist in the configured hardware — the 1516 has no onboard I/O, so %I0.0 / %Q0.0 don't exist. Insert a DI and a DQ module (starting at 0) and it's 0/0.
The order is fixed: register instance → power on → wait for Stop → download → RUN. A freshly registered instance is empty, which is why you wait for Stop before downloading. /sim/status returning 403 means exactly two things: TiaLink was started with --no-sim, or PLCSIM Advanced isn't installed.
Four scenarios surface something the compiler can't see and the diagram reads wrong:
Press the stop button and the fan doesn't stop immediately. The TOF input is Turn_On_PB AND NOT Turn_Off_PB — for a TOF, releasing the start button and pressing stop are the same falling edge, so the fan keeps running for another minute either way. Reading the ladder, "stop means stop" is the natural (and wrong) conclusion.
Which changes the deliverable: not "I looked at it, it's fine," but scenario table + measured values + one conclusion.
4.6 Cloud simulation: define the word "trigger"
The sixth lesson takes a lighter path: no TIA, no PLCSIM, no Windows. The same SCL goes to a cloud simulation MCP endpoint, executed scan by scan, turned into PASS/FAIL by a scenario table.
Setup is three steps: sign in, create a sim_live_ API key, add https://tia.hubwiz.com/sim/mcp to any Streamable HTTP MCP client. The endpoint exposes six tools (lad_* / scl_*); this lesson uses scl_validate, scl_simulate, scl_run_scenario.
Billing and fields worth knowing up front:
-
initialize,tools/list,resources/readare free; each acceptedtools/callcosts one credit. New accounts get 100; this lesson uses roughly 8–12. -
tickMsdefaults to 10 ms, so 100 ticks = 1 second. -
scl_simulatesteps inscans;scl_run_scenariosteps inticks. That's the easiest mistake to make.
The first acceptance run produces the course's signature failure (indented block below — the source page prints it with full scan counts):
PASS start latches, reset clears (3 step(s), 5 scan(s))
FAIL sensor A pulse gives a 2 s diverter pulse: step 3 scan 100: DiverterA expected true, got false
FAIL both sensors: A wins, only one output: step 2 scan 1: DiverterA expected true, got false
RESULT: FAIL (2 failure(s), 109 scan(s))
The same root cause as lesson 1: a TON requires IN to stay true for the full PT, and the sensor is high for exactly one scan. "Trigger, then output for 2 seconds" was implemented as "hold it for 2 seconds, then output" — two different requirements.
Switching to TP (fixed pulse width) passes the first three scenarios, and then a new boundary case fails: a TP pulse is not cut short by IN := FALSE. DiverterA := PulseA.Q AND NOT Reset merely masks the output while the pulse keeps running, so the diverter comes back on when reset is released. The final design is latch + TON to end the pulse: make "currently diverting" an explicit ActiveA/ActiveB state, let Reset clear the state, and interlock on the other side's Active rather than its output.
The ALL PASS run: 8 scenarios + 16 sweep combinations + a 5,000-scan fuzz = 5,735 scan cycles. The report replays identically on local scl-sim 0.1.0 and the hosted endpoint (2026-10-19): same SCL plus the same scenario file yields the same PASS/FAIL and scan counts.
4.7 Refactor with regression: TP typed as TON, clean compile, zero motors
The last lesson covers "change the structure, not the behavior." The target is a three-motor delayed-start sequence: one button opens a 20-second window, three motors start at +5 / +10 / +15 s, and everything stops after the window. The original writes TON + coil three times in one network, differing only in PT and output — classic copy-paste.
The refactor collapses it into one parameterized FB (Enable / Pt in, Q out) instantiated three times, with tag table, symbols and addresses untouched.
The author also crashed once, which is the point: IEC_Timer_0_DB was called as TON instead of TP. Compile: 0 errors, 0 warnings. Press the button: no motor moves. Switching back to TP and replaying the same scenario table brings behavior back point for point.
Which is why the two disciplines matter more than the code:
- Store a behavior baseline first. Same scenario table, run before and after, compare cell by cell. Refactoring without a baseline means using the plant as a test environment.
-
Trust only output bits and the scenario table. If a structured member (
DB.Ton.ET) can't be read, change the evidence — don't fill the gap with "looks right."
5. Who does what: the agent acts, you judge
The course deliberately minimizes the human's actions, because in industrial work the interesting question isn't "can the AI write code" but "which actions have to stay with a person."
| Step | The agent does | You must do |
|---|---|---|
| Write SCL | Read the project, add a CPU, generate the block, import, compile, self-fix from compiler output, clean up source files, save | State the requirement; approve the "report before change" step; spot-check the read-back table |
| Modify an example | Update the tag table, insert a contact, compile, read back structure | Confirm the boundary (only Main + tag table); confirm it's not a live project |
| Read a legacy project | Inventory devices/blocks/tags/HMI, export, summarize per block and network, flag unreferenced tags | Decide which findings escalate to safety items; review inferred vs unconfirmed |
| Change impact | Scan references, classify read/write and symbolic/absolute, map to hardware channels, dryRun
|
Decide whether to change it; confirm terminals and drawings; confirm saving |
| Virtual PLC | Add device, insert modules, import, compile, register, power on, download, read/write, fill the table | Click the TIA authorization prompt; check that "measured" values really came from reads |
| Cloud simulation | Write scenario JSON, run assertions, locate the failing scan | Verify the scenario table covers the requirement — especially the definition of "trigger" |
| Refactor + regression | Save the baseline, write the parameterized FB, replace, rerun, diff | Decide which blocks must not be "refactored while you're in there"; confirm replacing the original |
Short version: actions can be delegated, judgment cannot. Your part boils down to three kinds of moves: state the requirement and the boundary, approve before a change is written and before it is saved, and verify the evidence instead of the claim. The checklists exist to turn "a human took a look" into "a human verified something."
6. Four questions people ask
Do I need TIA Portal installed?
Not for the whole course. One of the seven lessons (cloud PASS/FAIL) never touches TIA — browser, account, and any Streamable HTTP MCP client. The other six need Windows plus TIA Portal V19.
Can TiaLink change my project on its own?
It doesn't save silently. It exposes Openness operations as MCP tools, so writes are explicit: preflight before import, no overwrite of same-named objects by default, no auto-save afterwards. "Import ≠ save" appears more than once in the seven lessons.
If cloud simulation passes, is the program fine?
No. Cloud simulation runs SCL scan semantics only — no bus, HMI, drives, safety circuits, and it is not the TIA compiler. What it is very good at is exactly the "compiles clean, behavior broken" class of bug, like TON where the requirement said "trigger."
Can AI-written blocks go straight into production?
I wouldn't. The course's stance is consistent: AI assists, the compiler and read-back decide, every change gets human review, and safety functions, interlocks and e-stops are not delegated. What ships isn't "AI-written code" — it's code that passed the acceptance chain.
7. Two ways to start
Path A — Windows + TIA Portal V19
- Open a sandbox project, start TiaLink on the same machine; the page header auto-detects the connection and project name.
- Add a Streamable HTTP MCP server at
http://localhost:8080/mcpwith aBearertoken; on another machine, replacelocalhostwith the TIA PC's LAN address. - Start with "modify the first example" (20 minutes, smallest diff, fastest verification), then go back to "write SCL to 0/0" (30 minutes).
- If the health check flags the allow-list, the first write triggers a TIA authorization dialog that only a human can confirm; running
TiaLink.Helper.exeonce avoids it.
Path B — no TIA available yet
- Open the cloud simulator, sign in with a QR code, create an API key (shown once — don't commit it).
- Set the MCP endpoint to
https://tia.hubwiz.com/sim/mcp. - Do the "no TIA install" lesson with the same
FB_Sorterthat compiled clean in path A — and watch it fail twice before it passes.
8. What the course deliberately does not provide
- No downloads. By design: no files land on disk; import goes through TiaLink with a preflight, and nothing is auto-saved.
- Cloud simulation only accepts examples or desensitized code. Don't paste a customer project; lessons that touch TIA run entirely on your machine, and project data stays in-house.
- Passing simulation is not commissioning. PLCSIM only simulates CPU behavior; bus, HMI, drives and safety circuits are out of scope. Cloud simulation is narrower still.
- Every change needs human review. Safety functions, interlocks, e-stops are not delegated; AI output is "unverified" by default.
- Version-specific. Everything was measured on TiaLink 1.1.0.0 + TIA Portal V19 + S7-PLCSIM Advanced 6.0. Different versions change error text and tool names — which is exactly why the course insists on structured results instead of matching error strings.
9. Who it's for, and who it isn't
For: engineers who know TIA Portal but don't trust AI-written blocks in a real project; people inheriting a legacy program who want a specification before touching it; anyone training juniors who needs a checkable practice path; technical leads deciding how far AI can go.
Not for: people who have never opened TIA Portal (start with the 60-example ladder library); anyone looking for "one-click ladder generation, download the project"; anyone who wants to skip human review and safety validation.
10. Takeaway
Read together, the seven lessons aren't about how much the AI can write. They describe an auditable delivery chain:
write → compile → read back → assess impact → simulate → PASS scenarios → regression shows behavior unchanged.
Every step has a criterion that doesn't depend on the AI claiming success. That's the part worth copying, even if you never use TiaLink or the cloud simulator: put evidence at every step, and AI actually gets to enter an engineering workflow.
Start with the 20-minute modify-an-example lesson, or the 35-minute cloud PASS/FAIL lesson.
Verification notes
- Course structure, lesson steps and all measured numbers (2 errors / 2 warnings, 36 operands, 51 tags with 6 unreferenced,
dryRunrewriting 27 tags, 5,735 scan cycles,1513F-1 PN,1516-3 PN/DP) come from the official course pages at tia.hubwiz.com/learn-lad/ai/ and its seven sub-pages, checked on 2026-10-20. - The stated test environment is TiaLink 1.1.0.0 + TIA Portal V19 + S7-PLCSIM Advanced 6.0; the cloud simulation report replays identically on
scl-sim 0.1.0and the hosted endpoint (2026-10-19). - This article does not independently reproduce the measurements; numbers and conclusions follow the official pages and may change with tool versions.
Further reading (all in Chinese)
- AI × Industrial / PLC guide
- Siemens PLC ladder logic example library: 60 importable exercises
- Taking over someone else's PLC program: 4 evidence steps before the first edit
- Ladder to SCL migration guide: what converts, what must be refactored, how to verify
- Practicing PLC without hardware: Factory I/O + OpenPLC virtual lab
This article was originally published in Chinese on hubwiz.com.
Top comments (0)