PLCcheck

Refactoring Legacy PLC Code: From Spaghetti to Structure

How to refactor messy legacy PLC code into maintainable structure. Covers identifying spaghetti code, step-by-step refactoring, when to refactor vs. rewrite, and practical examples.

·12 min read
PLCrefactoringlegacy codespaghetti codestructuremaintenancebest practicesSCL

Diesen Artikel auf Deutsch lesen

Refactoring Legacy PLC Code: From Spaghetti to Structure

"Spaghetti code" in PLCs looks like: one giant OB1 with 500 networks, no subroutines, hundreds of markers with no names, jump instructions that go in every direction, and modifications layered on top of each other over 20 years. This guide explains how to turn it into maintainable code — without breaking anything.

Signs of Spaghetti Code

Rule #1: Never Refactor a Running System Without Testing

Refactoring means changing the code structure without changing the behavior. But any change risks introducing bugs. Before touching anything:

  1. Back up the current program (verified backup — compare online vs. offline)
  2. Document the current behavior (observe a complete machine cycle, record outputs at each step)
  3. Create a test plan (how will you verify the refactored code works identically?)
  4. Plan a rollback (if something goes wrong, how fast can you restore the original program?)

Step 1: Extract Functional Blocks

Take sections of OB1 that handle a specific function and move them into their own blocks:

FunctionBefore (in OB1)After (separate block)
Conveyor controlNetworks 10–25FC_Conveyor
Filling stationNetworks 26–50FB_Filling (with instance DB)
Safety interlocksNetworks scattered throughoutFC_Safety (called first in OB1)
HMI interfaceNetworks scattered throughoutFC_HMI_Interface

How: In TIA Portal, select the networks, cut, create new FC/FB, paste. Update the OB1 to call the new block. Test immediately.

Step 2: Replace Markers with Structured Data

Instead of 50 individual markers (M 10.0, M 10.1, M 20.0, MW 30...), create a global data block with meaningful names:

Before:

M 10.0  — (unknown purpose)
M 10.1  — (unknown purpose)
MW 30   — (some setpoint)

After:

DB_Machine.Conveyor.Running    : BOOL
DB_Machine.Conveyor.Fault      : BOOL
DB_Machine.Filling.Setpoint    : INT := 1500

Step 3: Eliminate Jump Spaghetti

Replace SPB/SPBN/SPA patterns with IF/THEN/ELSE in SCL:

Before (AWL — hard to read):

L MW 10
L KF +3
!=F
SPBN =M020
U E 0.0
SPB =M021
SPA =M099
M021: ...
M020: ...
M099: NOP 0

After (SCL — readable):

IF #Step = 3 AND #Start_Button THEN
    // Step 3 with start pressed
ELSIF #Step = 3 THEN
    // Step 3 without start
END_IF;

Step 4: Parameterize Repeated Logic

If the same pattern appears for multiple machines/stations, create a parameterized FB:

Before: 10 copies of motor control logic with different addresses.

After: One FB_Motor with parameters (Start, Stop, Fault_Input, Motor_Output), called 10 times with different actual parameters.

Step 5: Move Constants to Data Blocks

Replace hardcoded values (magic numbers) with named constants in a parameter DB:

Before:

L KF +1500      // What is 1500? Speed? Temperature? Delay?
T MW 30

After:

DB_Parameters.Conveyor_Speed_Setpoint := 1500;  // rpm

When to Refactor vs. When to Rewrite

SituationRecommendation
Code works but is hard to maintainRefactor gradually
Small changes needed, code is messyRefactor the affected section only
Code has fundamental design problems (wrong architecture)Rewrite
Migration to new platform (S5→S7, S7-300→S7-1500)Combine migration with refactoring
No one understands the code at allDocument first (PLCcheck Pro), then decide

Golden rule: If you are migrating anyway, refactoring is "free" — you are already testing the entire program. This is the best time to improve structure.

Frequently Asked Questions

How do I refactor without stopping production?

Refactor in the offline project. Test thoroughly in simulation (PLCSIM). Deploy during a planned maintenance window. Have the original program ready for immediate rollback.

Should I convert everything to SCL during refactoring?

Not necessarily. Keep simple bit logic in KOP/FUP (easier to monitor online). Convert complex jump-heavy AWL to SCL. Convert calculations and data processing to SCL. Use the best language for each task.


Maintained by PLCcheck.ai. Last update: March 2026. Not affiliated with Siemens AG.

Related Articles

Analyze your PLC code with AI

PLCcheck Pro explains, documents, optimizes, and migrates PLC code — automatically.

Try PLCcheck Pro →
← Back to Blog

Not affiliated with Siemens AG. S5, S7, STEP 5, STEP 7, and TIA Portal are trademarks of Siemens AG.