Plak of importeer je IEC 61131-3 ST-code en krijg direct een helder state- of flow-diagram, automatische validatie en export naar 6 formaten. Gemaakt voor PLC-engineers en systeemintegrators.
PLC-state-machines leven als lange CASE-blokken — lastig te reviewen, nog lastiger over te dragen.
Van broncode naar een deelbaar diagram in drie stappen.
Typ of plak je Structured Text in de editor, of importeer een .txt-bestand. Syntax-highlighting helpt je meteen op weg.
De state-variabele wordt automatisch herkend. Kies het diagramtype dat het best bij je machine past.
Krijg een diagram, een validatiescore met controles en een overzicht van elke state en transitie — klaar om te delen.
Kies een voorbeeld en wissel tussen state en flow — dit zijn echte diagrammen die de tool hier ter plekke genereert.
Een compacte machine met vier states — de snelste manier om een diagram te lezen.
PROGRAM PRG_TrafficLight
VAR
xEnable : BOOL; // Master enable for the intersection
xPedestrian : BOOL; // Pedestrian request button
iStep : INT := 0; // State machine step
xRed : BOOL; // Red lamp output
xYellow : BOOL; // Yellow lamp output
xGreen : BOOL; // Green lamp output
xWalk : BOOL; // Pedestrian "walk" lamp
fbStepTimer : TON; // Phase timer
END_VAR
CASE iStep OF
0: // RED
xRed := TRUE;
xYellow := FALSE;
xGreen := FALSE;
xWalk := FALSE;
fbStepTimer(IN := TRUE, PT := T#5s);
IF xEnable AND fbStepTimer.Q THEN
fbStepTimer(IN := FALSE);
iStep := 10; // Go to green
END_IF;
10: // GREEN
xRed := FALSE;
xGreen := TRUE;
fbStepTimer(IN := TRUE, PT := T#8s);
IF fbStepTimer.Q THEN
fbStepTimer(IN := FALSE);
iStep := 20; // Time to clear the intersection
END_IF;
20: // YELLOW
xGreen := FALSE;
xYellow := TRUE;
fbStepTimer(IN := TRUE, PT := T#3s);
IF fbStepTimer.Q THEN
fbStepTimer(IN := FALSE);
IF xPedestrian THEN
iStep := 30; // Serve waiting pedestrians
ELSE
iStep := 0; // Back to red
END_IF;
END_IF;
30: // WALK
xRed := TRUE;
xYellow := FALSE;
xWalk := TRUE;
fbStepTimer(IN := TRUE, PT := T#6s);
IF fbStepTimer.Q THEN
fbStepTimer(IN := FALSE);
xWalk := FALSE;
iStep := 0; // Back to red
END_IF;
END_CASE;
PROGRAM PLC_PRG
VAR
// System Control Inputs
xStartKnop : BOOL; // Starts the batch process
xStopKnop : BOOL; // Pauses the process safely
xNoodstop : BOOL; // Emergency Stop (Active LOW)
xResetKnop : BOOL; // Resets faults
// Process Feedback Sensors
rActueelGewicht : REAL; // Current tank weight from load cells [kg]
rDoelGewicht : REAL := 500.0; // Target weight for raw material [kg]
xNiveauHoog : BOOL; // High level switch sensor (safety backup)
xNiveauLaag : BOOL; // Low level switch sensor (tank empty indicator)
// Actuator Outputs
xVulVentiel : BOOL; // Control valve for filling raw material
xMengMotor : BOOL; // Motor control for the tank mixer
xAfvoerVentiel : BOOL; // Control valve for discharging final product
// Internal State Machine Variables
diStap : DINT := 0; // Current step indicator for state machine
diVorigeStap : DINT := -1; // Tracking for ENTRY logic execution
xFoutActief : BOOL; // System fault flag
sStatusMelding : STRING; // Human-readable status message
// Process Timers
fbMengTimer : TON; // Timer for the mixing duration
fbVulTimeout : TON; // Safety timeout if filling takes too long
END_VAR
// =============================================================================
// GLOBAL SAFETY INTERLOCKS (Executed every cycle)
// =============================================================================
IF NOT xNoodstop THEN
diStap := 100; // Immediate jump to Emergency Stop State
END_IF;
// =============================================================================
// MAIN STATE MACHINE
// =============================================================================
CASE diStap OF
0: // IDLE STATE
sStatusMelding := "0 - System Idle. Awaiting Start.";
xVulVentiel := FALSE;
xMengMotor := FALSE;
xAfvoerVentiel := FALSE;
// Transition Condition
IF xStartKnop AND NOT xStopKnop AND NOT xFoutActief THEN
diStap := 10; // Proceed to Initialization
END_IF;
10: // INITIALIZATION
sStatusMelding := "10 - Initializing Process and Verifying Sensors.";
// Reset process timers
fbMengTimer(IN := FALSE);
fbVulTimeout(IN := FALSE);
// Transition Condition (Verify tank is ready and empty)
IF NOT xNiveauHoog THEN
diStap := 20; // Proceed to Filling
ELSE
xFoutActief := TRUE;
diStap := 90; // High level fault on startup
END_IF;
20: // FILLING RAW MATERIAL
sStatusMelding := "20 - Filling Valve Open. Dosing Material.";
xVulVentiel := TRUE;
// Run safety filling timeout
fbVulTimeout(IN := TRUE, PT := T#45s);
// Transition Conditions
IF rActueelGewicht >= rDoelGewicht THEN
xVulVentiel := FALSE;
diStap := 30; // Weight reached, go to Mixing
ELSIF fbVulTimeout.Q OR xNiveauHoog THEN
xVulVentiel := FALSE;
xFoutActief := TRUE;
diStap := 91; // Timeout or Overflow Fault
ELSIF xStopKnop THEN
xVulVentiel := FALSE;
diStap := 50; // Pause requested
END_IF;
30: // MIXING PROCESS
sStatusMelding := "30 - Mixing Agitator Running.";
xMengMotor := TRUE;
// Run mixing timer (e.g., 15 seconds)
fbMengTimer(IN := TRUE, PT := T#15s);
// Transition Conditions
IF fbMengTimer.Q THEN
xMengMotor := FALSE;
diStap := 40; // Mixing done, go to Discharge
ELSIF xStopKnop THEN
xMengMotor := FALSE;
diStap := 50; // Pause requested
END_IF;
40: // DISCHARGING TANK
sStatusMelding := "40 - Discharge Valve Open. Emptying Tank.";
xAfvoerVentiel := TRUE;
// Transition Conditions
IF NOT xNiveauLaag AND rActueelGewicht <= 5.0 THEN
xAfvoerVentiel := FALSE;
diStap := 0; // Tank is empty, return to Idle
ELSIF xStopKnop THEN
xAfvoerVentiel := FALSE;
diStap := 50; // Pause requested
END_IF;
50: // PAUSE STATE
sStatusMelding := "50 - Process Paused by Operator.";
// Keep all actuators safely off during pause
xVulVentiel := FALSE;
xMengMotor := FALSE;
xAfvoerVentiel := FALSE;
// Transition Condition (Resume or Abort)
IF xStartKnop AND NOT xStopKnop THEN
// Retain timers and jump back to previous execution state
IF rActueelGewicht < rDoelGewicht THEN
diStap := 20; // Resume Filling
ELSE
diStap := 30; // Resume Mixing
END_IF;
END_IF;
90: // FAULT: STARTUP HIGH LEVEL OVERFLOW
sStatusMelding := "90 - CRITICAL FAULT: Tank high level on startup.";
IF xResetKnop THEN
xFoutActief := FALSE;
diStap := 0;
END_IF;
91: // FAULT: FILLING TIMEOUT / OVERFLOW
sStatusMelding := "91 - CRITICAL FAULT: Filling timeout or sensor high active.";
IF xResetKnop AND NOT xNiveauHoog THEN
xFoutActief := FALSE;
diStap := 10; // Re-initialize
END_IF;
100: // EMERGENCY STOP ACTIVE
sStatusMelding := "100 - EMERGENCY STOP ACTIVE. Hard shutdown.";
xVulVentiel := FALSE;
xMengMotor := FALSE;
xAfvoerVentiel := FALSE;
// Transition Condition (Only allow escape if hardware E-stop is physically cleared)
IF xNoodstop AND xResetKnop THEN
diStap := 0; // Return to Idle safely
END_IF;
ELSE
// Catch-all safety for undefined states
diStap := 100;
END_CASE;
// =============================================================================
// TIMER FUNCTION BLOCK CALLS (Executed every cycle)
// =============================================================================
fbMengTimer();
fbVulTimeout();
PROGRAM PRG_ConveyorSorter
VAR
xStart : BOOL; // Start / run request
xPartPresent : BOOL; // Photo-eye: part on the belt
xScanDone : BOOL; // Vision scan finished
xIsReject : BOOL; // Scan result: bad part
xDiverted : BOOL; // Pusher reached end position
xFault : BOOL; // Any drive / sensor fault
xReset : BOOL; // Operator reset
xBelt : BOOL; // Belt motor output
xPusher : BOOL; // Divert pusher output
iStep : INT := 0; // State machine step
fbScan : TON; // Vision scan dwell timer
END_VAR
IF xFault THEN
iStep := 90; // Jump to fault from any state
END_IF;
CASE iStep OF
0: // IDLE
xBelt := FALSE;
xPusher := FALSE;
IF xStart AND xPartPresent THEN
iStep := 10; // Part detected, start transporting
END_IF;
10: // TRANSPORT
xBelt := TRUE;
fbScan(IN := TRUE, PT := T#1s);
IF fbScan.Q THEN
fbScan(IN := FALSE);
iStep := 20; // Hold under the scanner
END_IF;
20: // SCAN
xBelt := FALSE;
IF xScanDone THEN
IF xIsReject THEN
iStep := 40; // Bad part, push to reject lane
ELSE
iStep := 30; // Good part, pass through
END_IF;
END_IF;
30: // ACCEPT
xBelt := TRUE;
IF NOT xPartPresent THEN
iStep := 0; // Part has left the belt
END_IF;
40: // DIVERT
xBelt := FALSE;
xPusher := TRUE;
IF xDiverted THEN
xPusher := FALSE;
iStep := 0; // Reject pushed off, back to idle
END_IF;
90: // FAULT
xBelt := FALSE;
xPusher := FALSE;
IF xReset THEN
iStep := 0; // Cleared, back to idle
END_IF;
END_CASE;
Nog geen code? Bouw de machine op een canvas en laat de Designer er nette IEC 61131-3 Structured Text van maken.
Designer & Digital Twin — account + betaald abonnement
Splits het Designer-canvas en zie de I/O van je machine op een live 3D- of 2D-twin — draai daarna de sequence om het gedrag te testen.
Designer & Digital Twin — account + betaald abonnement
Alles wat je nodig hebt om PLC-logica te documenteren en te reviewen.
States als nodes, transities als pijlen — één-op-één met je PLC-logica.
Stroomschema met beslissingsruiten en globale overrides, conform IEC 61131-3.
Automatische score met controles op onbereikbare states, doodlopende paden en niet-gestopte timers.
Word, PDF, SVG, PNG, JSON en een volledig rapport.
Zoom, verschuif en pas het diagram in, met een vergrendeling tegen per ongeluk scrollen.
Volledige licht/donker-modus en wisselen tussen Nederlands en Engels.
Deel je diagram zoals jouw team werkt.
We gebruiken geen database voor je code. Alle geüploade Structured Text wordt volledig in het vluchtige geheugen (RAM) van de server verwerkt, uitsluitend voor de analyse en het renderen van het diagram. Je industriële code wordt direct en permanent vernietigd zodra je sessie eindigt. Je intellectueel eigendom blijft 100% van jou.
Wat teams vragen voordat ze het proberen.
Laat je e-mailadres achter en we laten je het weten zodra ST State Diagrammer openbaar gaat — plus de grote mijlpalen. Geen spam, altijd uitschrijven mogelijk.
Bedankt! We hebben je aanvraag ontvangen. We zetten je account op en mailen je de gegevens. Kijk in je inbox voor een bevestiging.