Object-Oriented Programming in OMRON PLCs: FB and ST Methods

James Nishida16 min read
HMI ProgrammingOmronTechnical Reference
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

Overview: What "Object-Oriented" Means in a PLC Context

Object-oriented programming (OOP) in PLCs is a structured approach to organizing control logic through modular, reusable, and clearly bounded code units. Unlike PC software where classes, inheritance, and polymorphism are first-class language features, PLC OOP borrows these concepts and adapts them to the deterministic, scan-based, real-time execution model required by industrial automation.

The PLCopen Guidelines for Object Orientation extend the IEC 61131-3 model to introduce object-oriented design choices on top of Program Organization Units, Function Blocks, and methods. As Control Engineering's PLC OOP article explains, the goal is to organize and simplify program elements using objects, methods, and properties — not to reproduce a Java or C# class hierarchy verbatim.

The strict definition of "object-oriented" does not exist in any PLC platform. OMRON's IEC 61131-3 implementation provides building blocks (encapsulation via Function Blocks, methods on FB instances, libraries) that emulate OOP concepts. Inheritance, the most common OOP feature, is not native to OMRON PLCs and must be emulated through composition.

OMRON Controller Families and Programming Tools

Family Typical Models Programming Tool OOP Capability
NJ/NX Machine Automation Controllers NJ101-9020, NJ301-1200, NJ501-1500, NX102-9000, NX502-1500 Sysmac Studio (1.40+) Full FB encapsulation, methods, properties, ST, libraries
CP1 Compact PLCs CP1H-X40DT-D, CP1L-EM30DT-D, CP1E-E20DR-A CX-Programmer 9.x FB instances, ST, no methods/properties
CJ2 Modular PLCs CJ2M-CPU31, CJ2M-CPU35, CJ2H-CPU68 CX-Programmer 9.x FB instances, ST, no native methods
CS1 Modular PLCs CS1G-CPU42H, CS1H-CPU65H, CS1D-CPU65S CX-Programmer 9.x FB instances, ST, no native methods
Power PMAC Motion Controllers CK3M-CPU301, CK3W-AX2323 Power PMAC IDE + ECAT Studio Script-based; OOP-style structuring possible but not native to the scripting language

For OOP-style development, the NJ/NX series with Sysmac Studio is the recommended platform. CP1, CJ2, and CS1 controllers support Function Blocks and Structured Text, but their programming environments lack the method and property bindings introduced in IEC 61131-3 Third Edition.

IEC 61131-3 Foundations: POUs, FBs, Methods, Properties

The IEC 61131-3 standard defines four programming languages: Ladder Diagram (LD), Function Block Diagram (FBD), Structured Text (ST), and Instruction List (IL — deprecated). It also defines the Program Organization Unit (POU) as the basic building block, with three types: PROGRAM, FUNCTION_BLOCK, and FUNCTION.

FUNCTION_BLOCK is the closest PLC equivalent of a class. It has:

  • Input, output, and in-out variables (the FB's interface)
  • Internal variables (the FB's private state)
  • An algorithm body in any of the IEC languages
  • Zero or more methods (added in IEC 61131-3 Third Edition)
  • Zero or more properties (added in IEC 61131-3 Third Edition)

Each FB instance in OMRON's environment holds its own copy of the internal variables — the FB is the "class," and the instance is the "object." This is the core encapsulation mechanism available on every OMRON PLC that supports FBs.

Methods in Sysmac Studio (NJ/NX)

A method is a procedure bound to a Function Block that operates on that FB's instance data. In Sysmac Studio, methods are written in ST or Ladder and exposed through the FB's interface. They are called using dot notation: myMotorInstance.Start();

Methods differ from external subroutines because:

  • They have implicit access to the FB's internal variables
  • They can return a value of any IEC data type
  • They can be called from programs, other FBs, or event tasks
  • They appear in the call graph of the FB, simplifying online debugging

Properties in Sysmac Studio

A property exposes a getter and optionally a setter for a value tied to FB instance state. myHeater.TemperatureSetpoint := 75.0; reads or writes the FB's internal setpoint variable. Properties are syntactic sugar over methods but improve code readability when the exposed value is logically an attribute rather than an action.

Properties are defined with three components in Sysmac Studio: a backing variable (internal VAR), a getter method (read-only or read/write), and an optional setter method. The runtime overhead of a property read is approximately the same as a direct variable access on NJ501 series controllers.

Function Blocks: The Core OOP Pattern in OMRON

For CP1, CJ2, CS1, NJ, and NX platforms, Function Blocks are the workhorse of structured, reusable code. An FB is created in CX-Programmer or Sysmac Studio by defining its variable table (input, output, in-out, internal) and its body, then instantiating it in a program.

Defining an FB: MotorController Example

Consider a MotorController FB that wraps start, stop, fault reset, and overload logic. In Sysmac Studio (ST syntax):

FUNCTION_BLOCK MotorController
VAR_INPUT
    StartCmd       : BOOL;
    StopCmd        : BOOL;
    FaultReset     : BOOL;
    OverloadInput  : BOOL;
END_VAR
VAR_OUTPUT
    Running : BOOL;
    Fault   : BOOL;
    AtSpeed : BOOL;
END_VAR
VAR
    State    : INT := 0;     // 0=Idle,1=Starting,2=Running,3=Stopped,4=Faulted
    RunTimer : TON;
END_VAR

// State machine body in Ladder or ST follows

Each instance maintains its own State and RunTimer. The same FB can be used for 50 different motors by creating 50 instances, each with a unique instance name and allocated memory.

Instance Memory and Task Allocation

On CP1H, an FB instance consumes a symbol table entry plus the internal variable memory. For a CPU with 32 Kwords of DM and 20 Ksteps of program memory (e.g., CP1H-XA40DT-D), FBs share the global DM area. Engineers must track instance memory manually because CX-Programmer versions older than 9.81 do not show instance variable allocation per FB in the project tree.

On NJ/NX, Sysmac Studio manages instance memory automatically. Variables are AT-specified to memory areas (e.g., AT %I0.0.0 for an NX-EC0122 EtherCAT input) and the compiler tracks usage. A typical NJ501-1300 has 2 MB of variable memory, supporting thousands of FB instances.

Structured Text for OOP-Style Algorithms

ST is the IEC 61131-3 Pascal-derived language that supports the syntax needed for OOP-like design: CASE, FOR, WHILE, IF...ELSIF, function/FB calls, and arrays/structures. While ST itself is not object-oriented, it is the language typically used for FB bodies and method bodies where OOP principles are applied.

Example: State Machine in ST

METHOD PUBLIC RunStateMachine : BOOL
VAR
    LocalTimeout : TIME;
END_VAR

CASE State OF
    0:  // Idle
        IF StartCmd AND NOT Fault THEN
            State := 1;
            RunTimer(IN := FALSE);
        END_IF;
    1:  // Starting
        RunTimer(IN := TRUE, PT := T#3S);
        IF RunTimer.Q THEN
            Running := TRUE;
            State  := 2;
        END_IF;
    2:  // Running
        IF OverloadInput THEN
            Fault   := TRUE;
            Running := FALSE;
            State   := 4;
        ELSIF StopCmd THEN
            Running := FALSE;
            State   := 3;
        END_IF;
    3:  // Stopped
        RunTimer(IN := FALSE);
        IF NOT StopCmd AND NOT StartCmd THEN
            State := 0;
        END_IF;
    4:  // Faulted
        IF FaultReset THEN
            Fault := FALSE;
            State := 0;
        END_IF;
END_CASE;

RunStateMachine := Running;

This single method encapsulates the full state machine. Multiple MotorController instances each carry their own State, RunTimer, and output variables — true instance-level encapsulation.

Implementing Methods and Properties in NJ/NX

Sysmac Studio version 1.20 and later supports methods and properties on FBs, aligning with IEC 61131-3 Third Edition. The method and property definitions are stored as part of the FB symbol in the project tree under the "Programming" → "POUs" node.

Adding a Method to an FB

  1. Right-click the FB in the Multiview Explorer and select "Add" → "Method."
  2. Name the method (e.g., Start, Stop, ResetFault).
  3. Choose the implementation language (ST or Ladder).
  4. Define the method's local variables and return type (BOOL, INT, REAL, STRING, etc.).
  5. Implement the method body. The method has implicit access to the FB's VAR, VAR_INPUT, and VAR_OUTPUT sections.
  6. Compile and download. The method is part of the FB and travels with the instance.

Calling Methods

// In a program section (ST)
IF bStartRequest THEN
    Motor1.Start();          // Call Start method on Motor1 instance
    bStartRequest := FALSE;
END_IF;

IF bResetRequest THEN
    Motor1.ResetFault();     // Call ResetFault method
END_IF;

nSetpoint := Motor1.SpeedSP;  // Read property
Motor1.SpeedSP := 1200;       // Write property
bRunning := Motor1.IsRunning; // Read BOOL property
Methods and properties are only available on NJ/NX controllers with Sysmac Studio 1.20 or higher. CP1, CJ2, and CS1 platforms do not support methods/properties natively. The workaround is to create separate subroutines that receive the FB instance as an in-out variable, then call that subroutine from the program.

Inheritance and Polymorphism: Practical Patterns

OMRON PLCs do not implement class inheritance. However, two patterns emulate inheritance effectively.

Pattern 1: Composition with Interface FBs

Define a "base" FB containing common variables and methods, then include an instance of that FB inside the "derived" FB. Access the base methods through the instance name.

FUNCTION_BLOCK BaseIO
VAR
    RawInput : BOOL;
END_VAR
METHOD PUBLIC ReadInput : BOOL
    ReadInput := RawInput;
END_METHOD
END_FUNCTION_BLOCK

FUNCTION_BLOCK DerivedSensor
VAR
    Base    : BaseIO;        // Composition (acts as inheritance)
    CalGain : REAL := 1.0;
END_VAR
METHOD PUBLIC ReadScaled : REAL
    ReadScaled := Base.ReadInput() * CalGain;
END_METHOD
END_FUNCTION_BLOCK

Composition adds a level of indirection but avoids the inheritance vs. memory trade-off that ladder programmers complained about. On NJ501 series, the cost of an extra instance variable slot is negligible.

Pattern 2: Interface Convention Through Naming

Define naming and method conventions (e.g., all pump FBs must implement Start, Stop, GetStatus) and use a generic wrapper FB that holds an array of references or iterates over a named instance group. This is closest to "polymorphism" in PLC land — the same wrapper code calls the same-named method on each instance, even though the implementations differ.

For example, a PlantSupervisor FB that loops over Conveyor1.Start(), Pump1.Start(), Valve1.Start() in sequence does not require an inheritance hierarchy — it requires only that each FB implement the method by the same name. Sysmac Studio's auto-complete and IntelliSense make this pattern feasible at the development level.

Library Management and Versioning

Reusable FBs in OMRON are packaged as libraries. Sysmac Studio uses .slr (Sysmac Library Repository) files; CX-Programmer uses .cxf or .cxl files. Library management is critical for OOP-style reuse because library updates must not break existing projects.

Library Lifecycle

  1. Author: Create FBs in a dedicated library project. Use Sysmac Studio's "Create Library" function (Project → Library → Create).
  2. Version: Increment the library version field (e.g., 1.0.0 → 1.1.0). Add a _CHANGELOG.txt or a method that returns version info.
  3. Distribute: Export to a repository (OMRON's Sysmac Library portal, internal SVN/Git repository).
  4. Consume: Reference the library in a project; the FB instances become available in the toolbox.
  5. Update: When a new library version is published, project users see a notification and can accept or defer the update.

OMRON publishes validated libraries for motion, safety, vision, and process control on the OMRON industrial automation portal. Third-party vendors also publish FB libraries following the same .slr mechanism, which simplifies vendor integration in mixed-vendor systems.

Library Reference Modes

Sysmac Studio supports two library reference modes:

  • Reference: Project links to the external .slr file path. Updates are picked up automatically when the file is replaced.
  • Embedded: The library is copied into the project .csm file. The project is self-contained, but updates require a manual re-import.

For multi-developer teams, use Reference mode with a shared network drive or Git LFS to ensure all team members see the same FB definitions.

Performance and Memory Considerations

OOP-style code trades memory for maintainability. Engineers must understand the cost of each FB instance and method call before designing a large system.

Scan-Time Impact

On NJ501 series, a typical FB instance adds 0.5–5 µs of scan time per call, depending on the number of internal variables, TON/TOF timers used, and whether the FB contains nested FB calls. A state-machine FB with 20 internal variables and three timers costs approximately 2–4 µs per scan on an NJ501-1300 at a 2 ms task period. Method call overhead on the same controller is 0.1–0.5 µs per invocation, comparable to a function call on the same platform.

Item CP1H-Y20DT-D CJ2M-CPU35 NJ501-1500
Program memory 20 Ksteps 60 Ksteps 20 MB
DM / variable area 32 Kwords 160 Kwords 2 MB variable memory
FB instances supported (typical) ~200 ~2,000 ~10,000+
Method call overhead N/A (no methods) N/A (no methods) 0.1–0.5 µs
ST execution speed 1.6 µs/instruction 0.04 µs/instruction 0.003 µs/instruction
Min task period 1 ms 0.5 ms 0.25 ms (high-speed task)
The "you'll need a much bigger and more expensive PLC" critique is partly valid for older CP1/CJ1 platforms where each FB instance consumed significant DM and program memory. On NJ/NX with multi-megabyte variable memory, this concern is largely obsolete — the NJ101-9020 entry-level MAC still supports thousands of FB instances and full method/property support.

Memory Profiling Steps

  1. Open the project in Sysmac Studio and connect to the controller (online).
  2. Navigate to "Controller" → "Memory Allocation" to view current variable and program usage.
  3. Enable the task period monitor in "Configuraion and Setup" → "Task Settings."
  4. Run the machine through worst-case cycle (full product changeover, alarm reset, etc.).
  5. Note peak task time. If peak exceeds 70% of task period, refactor heavy FBs into slower tasks or split logic across periodic tasks.

Best Practices for OOP in OMRON PLCs

  1. One FB per physical asset. Wrap each motor, valve, sensor, or PID loop in its own FB. Avoid creating "god" FBs that handle 20 different functions.
  2. Keep the interface minimal. Expose only what callers need. Internal variables should remain internal — do not mark every variable as VAR_OUTPUT.
  3. Use methods for actions, properties for state. Reserve Start, Stop, Reset as methods. Expose SpeedSP, Pressure, Status as properties.
  4. Reuse via libraries, not copy-paste. Centralize a motor FB in a library; reference it from every project. Update the library once, propagate everywhere.
  5. Version everything. Tag library releases with major.minor.patch. Document breaking changes in a method-accessible changelog.
  6. Limit nesting depth. FBs calling FBs calling FBs compounds scan time and obscures the call stack. Three levels of nesting is a practical limit.
  7. Test FBs in isolation. Use Sysmac Studio's simulation mode (NJ/NX) to verify FB logic without a physical rack. On CP1/CJ2, use CX-Simulator.
  8. Avoid global variables inside FBs. Globals defeat encapsulation. If two FBs need to share data, pass it explicitly through in-out parameters.
  9. Use retain attributes deliberately. Mark only the variables that must survive a power cycle as Retain. Non-retained variables initialize to default values on every cold start.

Troubleshooting OOP Code

Symptom Likely Cause Resolution
"Undefined method" error at compile Sysmac Studio version older than 1.20, or FB was upgraded in newer version Update Sysmac Studio; refresh library references via Project → Library → Update
FB instance variables reset on power cycle unexpectedly Internal variables not marked Retain Check the Retain attribute on the VAR section; set to Retain for state that must survive power-off
Scan time increased after adding FBs Excessive FB nesting, large state machines, or string operations in ST Profile with Sysmac Studio's Task Period monitor; refactor heavy operations to background tasks
Library cannot be opened in older project Library created with newer Sysmac Studio version Recompile library targeting the minimum supported version; document minimum in release notes
Method returns unexpected value Method called before FB inputs updated in scan Verify scan order; place FB input assignments before method call in the program section
Property read returns stale value Setter never invoked; backing variable updated directly bypassing the setter Update backing variable only through the property setter; mark internal VAR as Protected where possible
Online edit of FB body fails Controller in RUN mode without online edit support for that FB Switch to PROGRAM mode, or download full project; verify Sysmac Studio 1.30+ for full online edit support

CX-Programmer vs Sysmac Studio: OOP Feature Comparison

Feature CX-Programmer 9.x Sysmac Studio 1.40+
Function Block instances Yes Yes
Structured Text Yes Yes
Methods on FBs No Yes (IEC 61131-3 3rd Ed.)
Properties on FBs No Yes
FB inheritance No No (emulated via composition)
Library format .cxf, .cxl .slr
Integrated simulation CX-Simulator (separate install) Built-in simulator with virtual rack
Online edit of FB bodies Limited Yes, with change tracking
Version control integration File-based, no native git Project export to file set, import into git
ST debugging breakpoints No Yes (Sysmac Studio 1.25+)
3rd party library marketplace Limited OMRON Sysmac Library portal

Standards Reference

The OMRON implementation tracks IEC 61131-3 Third Edition, which is the international standard for PLC programming languages. Engineers specifying or auditing OOP code on OMRON should reference:

  • IEC 61131-3:2013 — Programmable controllers, Part 3: Programming languages (Third Edition). The methods and properties definitions are in Section 6.5.2; the FUNCTION_BLOCK definition is in Section 6.5.1.
  • PLCopen Guidelines for Object Orientation — Extension documents for OO concepts on top of IEC 61131-3, published by PLCopen.

OMRON's Sysmac Studio libraries published on the OMRON industrial automation portal conform to the OMRON FB Style Guide, which encodes the conventions described above as default templates. When auditing third-party libraries, verify that the FB signatures match the OMRON conventions for input ordering (Cmd, Status, Setpoint, Feedback) to ensure interchangeability across projects.

Practical Migration Path: CX-Programmer FBs to Sysmac Studio Methods

Engineers with existing CP1/CJ2/CS1 code can migrate to NJ/NX without rewriting the FB logic. The FB body, variable table, and instance names transfer directly. The migration steps are:

  1. Open the CX-Programmer project in Sysmac Studio using the Import CX-Project tool (File → Import → CX-Programmer Project).
  2. Sysmac Studio maps the existing FB instances and translates the ladder or ST body. Internal variables are preserved.
  3. Add methods to the imported FB that wrap the existing body logic. The original FB body becomes the default method (often Execute or Run).
  4. Expose critical state variables as properties for external read/write.
  5. Update library references to use the new .slr file instead of .cxf.
  6. Compile, simulate, and download to the new NJ/NX controller.

The migration is largely mechanical. Most of the time is spent validating that the new method call points match the old program sequence. Existing ladder sections are preserved by Sysmac Studio as separate POU instances of the same FB.

Does OMRON support full OOP with class inheritance?

No. OMRON's IEC 61131-3 implementation on NJ/NX supports encapsulation (Function Blocks), methods, and properties, but not class inheritance. Engineers emulate inheritance through composition (an FB containing an instance of a "base" FB) or by enforcing naming conventions across sibling FBs.

What is the minimum Sysmac Studio version for methods and properties?

Sysmac Studio 1.20 introduced methods and properties for FBs on NJ-series controllers. Version 1.40 or later is recommended for current feature support, including the latest library format and integrated simulator improvements. Sysmac Studio 1.50 added extended debug features for FB methods, including per-method breakpoints and call-stack inspection.

Can I use Function Blocks on a CP1H or CJ2M PLC?

Yes. CP1, CP1H, CP1L, CJ1, CJ2, and CS1 controllers all support Function Block instances defined in CX-Programmer. However, these platforms do not support methods or properties on FBs — those features require NJ/NX with Sysmac Studio. The standard workaround for older platforms is subroutine-based "methods" that take the FB instance as an in-out variable, providing similar encapsulation without the syntactic sugar.

How much scan-time overhead does a typical FB add?

On an NJ501-1500, a state-machine FB with 20 internal variables and three TON timers adds approximately 2–4 µs per scan. On a CJ2M-CPU35, the same FB adds approximately 30–80 µs. Profile the actual cost using Sysmac Studio's task monitor or CX-Programmer's cycle time display — heavy nesting (3+ levels) compounds overhead and can push scan time beyond task period, causing task overruns.

Is OOP in PLCs faster or slower to develop than ladder?

For complex algorithms (state machines, math, batch logic, motion sequences), OOP-style FBs in Structured Text are typically 30–50% faster to develop and 3–5× easier to maintain than equivalent ladder. For simple discrete I/O logic (a single solenoid, an interlock), ladder remains more efficient. The productivity crossover is around 50–100 lines of logic per device — beyond that, FB+ST wins; below that, ladder wins on raw development time.

Back to blog