Tutorial #5: Prompt Engineering for IEC 61131-3 ST Code Generation
Controlled AI Code Drafting
โ CORE MISSION OF THIS TUTORIAL
By the end of this tutorial, the reader will be able to:
- โ Understand what prompt engineering really is in engineering terms
- โ Control format, structure, and limitations of generated PLC code
- โ Generate read-only IEC 61131-3 Structured Text (ST) drafts
- โ Prevent unsafe, hallucinated, or uncontrolled code generation
- โ Prepare for Few-Shot Validation in Tutorial #6
This tutorial establishes the human-to-AI control interface for industrial code generation.
โ ๏ธ SAFETY BOUNDARY REMINDER
This tutorial provides recommendations only.
It must never be connected to:
- Live PLCs
- Production deployment pipelines
- Safety-rated controllers
- Motion or power systems
> All outputs are advisory-only and always require explicit human approval before any real-world action.
๐ VENDOR-AGNOSTIC ENGINEERING NOTE
This tutorial uses:
- โธ Generic IEC 61131-3 Structured Text (ST)
- โธ Standard Python + OpenAI client
- โธ No PLC runtimes, hardware connections, or vendor SDKs
The patterns apply equally to TwinCAT, Siemens TIA Portal (SCL), CODESYS, Rockwell ST, and all IEC-compliant environments.
1๏ธโฃ CONCEPT OVERVIEW โ WHAT PROMPT ENGINEERING REALLY IS
In engineering terms: A prompt is a control interface, not a question.
Bad mental model:
"I ask the AI something nicely."
Correct mental model:
"I specify operating constraints for a probabilistic system."
For PLC generation, prompt engineering controls:
- โ Output format
- โ Language (ST only)
- โ Scope (no overreach)
- โ Safety boundaries
- โ Determinism (via temperature=0, though not strictly guaranteed)
Note on Determinism: While setting temperature=0 increases consistency, LLM outputs are never 100% deterministic. Identical prompts may occasionally produce slightly different formatting or phrasing. Always review generated code.
2๏ธโฃ REFERENCE ARCHITECTURE โ HUMAN-IN-THE-LOOP CODE DRAFTING
Controlled Code Generation Pipeline
graph LR
A[Engineer<br/>Define Requirements] --> B[Structured Prompt<br/>Constrained Input]
B --> C[LLM<br/>Generate ST Code]
C --> D[Read-Only Draft<br/>No Execution]
D --> E[Engineer Review<br/>Human Validation]
E --> F{Acceptable?}
F -->|No| A
F -->|Yes| G[Manual Integration]
style A fill:#1a1a1e,stroke:#00ff7f,stroke-width:2px,color:#00ff7f
style B fill:#1a1a1e,stroke:#9e4aff,stroke-width:2px,color:#fff
style C fill:#1a1a1e,stroke:#9e4aff,stroke-width:2px,color:#fff
style D fill:#1a1a1e,stroke:#fec20b,stroke-width:2px,color:#fec20b
style E fill:#1a1a1e,stroke:#00ff7f,stroke-width:2px,color:#00ff7f
style F fill:#1a1a1e,stroke:#ff4fd8,stroke-width:2px,color:#ff4fd8
style G fill:#1a1a1e,stroke:#00ff7f,stroke-width:2px,color:#00ff7f Human authority at every step โ LLM is a text generator, not a decision maker
Boundaries
- โ AI generates text only
- โ No compilation
- โ No download to PLC
- โ No execution
- โ Human is always the gatekeeper
3๏ธโฃ CLEAN EDUCATIONAL SCENARIO
We want to generate a very simple IEC 61131-3 ST motor start/stop block:
Requirements
- โธ Boolean inputs: StartButton (momentary), StopButton (momentary)
- โธ Boolean output: MotorRunning (latched)
- โ Stateful start/stop behavior (set/reset pattern)
- โ No timers, safety interlocks, or fault handling
- โธ Priority: Stop takes precedence if both buttons pressed
We will learn how to force the LLM to stay inside these boundaries.
Why Prompt Structure Matters
Compare two fundamentally different approaches to AI code generation:
โ Uncontrolled Prompt
graph LR
A[Vague Prompt] --> B[LLM]
B --> C[Unpredictable Output]
C --> D[โ Risk]
style A fill:#1a1a1e,stroke:#ff4fd8,stroke-width:2px,color:#ff4fd8
style B fill:#1a1a1e,stroke:#9e4aff,stroke-width:2px,color:#fff
style C fill:#1a1a1e,stroke:#fec20b,stroke-width:2px,color:#fec20b
style D fill:#1a1a1e,stroke:#ff4fd8,stroke-width:2px,color:#ff4fd8 Dangerous: Adds safety logic, timers, features you didn't ask for
โ Controlled Prompt
graph LR
A[Structured Prompt] --> B[LLM]
B --> C[Constrained Output]
C --> D[โ
Reviewable]
style A fill:#1a1a1e,stroke:#00ff7f,stroke-width:2px,color:#00ff7f
style B fill:#1a1a1e,stroke:#9e4aff,stroke-width:2px,color:#fff
style C fill:#1a1a1e,stroke:#04d9ff,stroke-width:2px,color:#fff
style D fill:#1a1a1e,stroke:#00ff7f,stroke-width:2px,color:#00ff7f Safe: Generates only what you specified, in a reviewable format
4๏ธโฃ PRACTICAL EXPERIMENTS
๐งช Experiment 1: Uncontrolled vs Controlled Prompt
Objective
See the difference between a loose prompt (unsafe, verbose) and a controlled prompt (deterministic, auditable).
Part A โ Uncontrolled Prompt (What NOT to Do)
from openai import OpenAI
client = OpenAI()
bad_prompt = "Generate PLC code for a motor controller."
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "user", "content": bad_prompt}
]
)
print(response.choices[0].message.content) Expected (Unstable) Output May Include:
โ Safety logic you didn't ask for
โ Timers
โ Fault latching
โ Vendor-specific constructs
โ Commentary mixed with code
This is unreviewable and unsafe by construction.
Part B โ Controlled Engineering Prompt (IEC 61131-3 ST)
controlled_prompt = '''You are generating IEC 61131-3 Structured Text (ST) only.
Rules:
- Output only code.
- No comments.
- No safety logic.
- No timers.
- No vendor-specific libraries.
- No additional features.
Task:
Create a basic motor start/stop logic with:
Inputs:
- StartButton : BOOL (momentary pushbutton, rising edge triggers start)
- StopButton : BOOL (momentary pushbutton, rising edge triggers stop)
Output:
- MotorRunning : BOOL (latched output, persists across PLC scans)
Behavior:
- Use a set/reset pattern (stateful across scans).
- MotorRunning becomes TRUE when StartButton is pressed.
- MotorRunning becomes FALSE when StopButton is pressed.
- If both buttons pressed simultaneously, StopButton takes priority (safety first).
'''
response = client.chat.completions.create(
model="gpt-4o-mini",
temperature=0, # For more deterministic output
messages=[
{"role": "user", "content": controlled_prompt}
]
)
print(response.choices[0].message.content) Example Output (Actual results may vary slightly)
IF StartButton THEN
MotorRunning := TRUE;
END_IF;
IF StopButton THEN
MotorRunning := FALSE;
END_IF; - โ Read-only draft
- โ No execution
- โ Human-reviewed
- โธ Cost: Varies by model/pricing | Runtime: typically seconds
๐งช Experiment 2: Forcing Output Structure with a Generic ST Code Template
Objective
Force the AI to generate only inside a predefined IEC 61131-3 ST template.
Python Code
template_prompt = '''Generate ONLY the executable ST code that fills the body below.
CRITICAL INSTRUCTIONS:
- Output ONLY the code that goes in the <INSERT CODE HERE> section.
- Do NOT repeat the VAR blocks or template structure.
- Do NOT add comments or explanations.
- Use a set/reset pattern for stateful motor control.
TEMPLATE:
VAR_INPUT
StartButton : BOOL; (* Momentary pushbutton *)
StopButton : BOOL; (* Momentary pushbutton *)
END_VAR
VAR_OUTPUT
MotorRunning : BOOL; (* Latched output *)
END_VAR
(* CODE BELOW *)
<INSERT CODE HERE>
'''
response = client.chat.completions.create(
model="gpt-4o-mini",
temperature=0, # For more deterministic output
messages=[
{"role": "user", "content": template_prompt}
]
)
print(response.choices[0].message.content) Expected Output
IF StartButton THEN
MotorRunning := TRUE;
END_IF;
IF StopButton THEN
MotorRunning := FALSE;
END_IF; Interpretation
- โธ โ Structural confinement
- โธ โ No unsafe expansion
- โธ โ Draft-only output (body code only)
- โธ Cost: Varies by model/pricing | Runtime: typically seconds
๐ EXPLICIT OPERATIONAL PROHIBITIONS
- โ Using generated code directly in production
- โ Downloading code to PLCs
- โ Bypassing code review
- โ Generating safety logic without validation
- โ Trusting output without human inspection
โ KEY TAKEAWAYS
- โ A prompt is a safety and control interface
- โ Unstructured prompts produce unreviewable risk
- โ Structured prompts produce auditable drafts
- โ You can fully control: Language, Scope, Features, Format
- โ AI must be treated like a junior engineer under supervision
๐ NEXT TUTORIAL
#6 โ Few-Shot Learning for PLC Validation
You will extend this system by supplying validated PLC examples, teaching the AI what 'good' looks like, and improving consistency across generations.
๐งญ ENGINEERING POSTURE
This tutorial enforced:
- โธ Constraint-first design over creative freedom
- โธ Draft-only generation over execution
- โธ Human authority over machine output
- โธ Reviewability over automation
โ END OF TUTORIAL #5