PLC Function Block Instance Management: Single vs Unique FBs

James Nishida13 min read
Best PracticesHMI ProgrammingOmron
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

PLC Function Block Instance Management: Single vs Unique Function Blocks on CJ1W-CPU43

Function blocks (FBs) are reusable code blocks that encapsulate logic along with their own persistent working memory. The question of whether one FB instance can serve multiple field devices — or whether each device requires its own instance — is one of the most consequential memory-management decisions a PLC programmer makes on a CJ1W-CPU43 project. Misallocating instances leads to silent calculation errors, especially with PID loops, timers, and any block that retains state between scans.

This reference documents the instance-memory model used by Omron CX-Programmer FBs, the rules that govern single-instance reuse, the hard instance limits that vary by CPU model, and the practical diagnostics used to verify correct instance allocation in the field.

FB Instance Memory Model in CX-Programmer

An Omron Function Block is a compiled code block plus a private working-data area. The working-data area is called an instance. When you drag an FB into a ladder section, CX-Programmer generates a unique instance (for example, SCALE_001) and reserves a slice of the CPU's FB Instance Area for it. Every variable declared inside the FB — inputs, outputs, internal flags, timers, counters, and any retained work registers — lives in that slice.

Three properties follow from this model:

  1. The instance is persistent. Values written into internal variables survive between scans, between cycles, and across power-cycle retentive handling if the variables are declared retentive.
  2. The instance is exclusive. No two FBs share the same instance unless you deliberately reuse the same instance name.
  3. The instance consumes finite memory. Every instance reduces the remaining instance budget of the CPU by the FB's declared footprint in 16-bit words.

The FB Program Area and the FB Instance Area are two distinct allocations tracked separately by the CPU. The Program Area holds the compiled code of each unique FB definition. The Instance Area holds the per-instance working data. Refer to the Omron CJ1G-CPU43 Operation Manual (W393) for exact partitioning; the instance budget is the figure that constrains how many instances you can create, regardless of how many FB definitions are loaded.

Single-Scan vs Multi-Scan FB Classification

The decision to share a single instance or to allocate one instance per field device rests on a single question: Does the FB finish all of its work within a single execution pass, or does it carry state forward from one scan to the next?

Single-Scan FBs (Safe to Share)

A single-scan FB reads its inputs, performs a deterministic transform, and writes its outputs within one invocation. It does not store intermediate results between scans. Examples include:

  • Analogue input scaling (raw integer → engineering units, e.g., 0–27648 → 0.0–100.0 °C)
  • Linearisation with a polynomial or lookup table evaluated entirely from inputs
  • Unit conversions (°F → °C, mbar → Pa, Hz → RPM)
  • Boolean combinational logic lifted into a reusable block
  • Alarm-limit comparison (input in, alarm out, no hysteresis state)

For these FBs, a single instance can be reused at every call site without semantic error, because the FB discards its working memory at the end of each call. Reuse preserves instance memory, which is the primary motivator on memory-constrained CPUs.

Multi-Scan FBs (Require Unique Instances)

A multi-scan FB retains internal state across executions. It performs incremental computation that depends on the previous scan's values. Examples include:

  • PID control with integral and derivative accumulation
  • Totalisers and running averages
  • Sequencers and step-state machines
  • On-delay, off-delay, and pulse timers used as latches or re-trigger blocks
  • Hour meters, run-time accumulators, and event counters
  • First-order lag filters and moving-average filters
  • Lead-lag compensators with internal filter state

If two PID loops share one instance, the integral term computed during loop A's scan is overwritten by loop B's scan before loop A reads it back. The PID output then tracks whichever loop was executed last, with stale state from the other loop contaminating the next pass. The result is unstable, oscillatory, or biased control that appears to work during commissioning but fails under load.

Engineering rule: If the FB contains any TIM, CNT, ACC, retentive variable, or self-referential equation that uses a value produced in a prior scan, allocate one instance per call site. Sharing is only safe for purely combinational logic that produces outputs strictly from current inputs.

CJ-Series CPU Instance Budget Reference

The CJ1W-CPU43 (and the broader CJ1G/CJ1M/CJ1H family) imposes a hard ceiling on the number of FB instances that can exist simultaneously in the project. The ceiling depends on the CPU model and on the FB Instance Area allocation within user memory.

CPU Model Approximate Instance Limit Typical Use Case
CJ1M-CPU11 / CPU12 Lower budget (verify in W394) Small machine, 1–2 PID loops
CJ1M-CPU21 / CPU22 / CPU23 Mid-range Mid-size cells, several PID loops
CJ1G-CPU42 / CPU43 / CPU44 / CPU45 128 instances (CPU43 baseline) Process skids, multi-loop control
CJ1H-CPU65 / CPU66 / CPU67 / CPU68 Larger instance budget High-density process lines

The 128-instance ceiling for the CJ1W-CPU43 is the baseline figure cited in CX-Programmer FB reference material. Higher-tier CPUs in the family support proportionally more instances. Because the exact figure depends on the FB Program Area, Instance Area, and the FB definition size in 16-bit words, always confirm the budget against the connected CPU's resource report in CX-Programmer before committing to the architecture.

To read the current instance consumption in CX-Programmer, open PLC → Memory Allocation or compile the project and inspect the compile log. The instance count is reported as FB Instances Used / FB Instances Available in the same dialog where DM, CIO, and WR allocations are displayed.

PID Block Instance Requirements in Detail

The PID instruction in Omron CJ-series — whether the legacy PID(190) or the enhanced PIDAT(191) — is the canonical example of a multi-scan FB. The instruction maintains six working words per loop: process variable, set point, proportional band, integral time, derivative time, and the accumulated MV bias. The integral term is updated additively every scan and depends on the error observed in the previous scan.

When a PID block is implemented as an FB with these internal variables, the FB instance holds the integrator state. Two consequences follow:

  1. One instance per controlled loop. A PID FB wrapping a furnace zone, an extruder barrel zone, and a coolant valve cannot share a single instance — each zone has its own PV, SP, integrator, and MV. Allocate PID_ZONE1, PID_ZONE2, and PID_ZONE3 with separate instances.
  2. No aliases or pointer tricks. Reusing the same instance across two PID FB bodies does not multiplex — it overwrites. The MV output seen on scan N+1 is whichever loop ran on scan N, plus whatever integrator residue the other loop left behind.

For autotune-capable loops on the CJ1W-CPU43, the AT input triggers the CJ1's autotuner against the current instance's PV and SP. A shared instance will autotune against whichever loop most recently wrote the instance, producing a tuning result that does not correspond to the loop you intended.

The same rule applies to derivative-on-PV versus derivative-on-error: the derivative term is computed from the difference between the current PV and the previous PV held in the instance. If that previous PV belongs to a different loop, the derivative action becomes a cross-coupling disturbance that will not stabilise no matter how the gains are tuned.

Instance Sharing Patterns and Code Layout

Pattern A: One-Instance Scaling Bank

Use a single SCALE_AI instance for all 0–10 V / 4–20 mA analogue inputs. The FB body executes once per rung per scan, writes the scaled result to its output parameter, and exits. There is no integrator, no latched comparator, no timer. The instance memory holds only the constants (low-scale, high-scale, raw-low, raw-high) declared as FB-internal constants — these are read-only and do not change between calls.

| SCALE_AI ( AI_RAW, MIN_RAW, MAX_RAW, MIN_EU, MAX_EU ) → AI_EU |
   |        ↑              ↑            ↑           ↑         ↑          |
   |  D100 (raw word)   0           27648       0.0        100.0        |
   |                                                                    |
   |  Rung 2: SCALE_AI (D200, 0, 27648, 0.0, 50.0) → D300              |
   |  Rung 3: SCALE_AI (D300, 0, 27648, 0.0, 200.0) → D400             |

All three rungs share the same instance. The body computes the scaling equation EU = (RAW - MIN_RAW) / (MAX_RAW - MIN_RAW) * (MAX_EU - MIN_EU) + MIN_EU purely from the inputs of the current rung. No state is carried forward.

Pattern B: Unique-Instance PID Bank

Each PID loop gets its own instance. The FB body executes once per scan, but the integrator and derivative state persists.

|  PID_ZONE1 ( PV:=D100, SP:=D102, P:=10.0, I:=60.0, D:=0.0, AT:=W0.00 ) → MV:=D110 |
|  PID_ZONE2 ( PV:=D200, SP:=D202, P:=12.0, I:=45.0, D:=0.0, AT:=W0.01 ) → MV:=D210 |
|  PID_ZONE3 ( PV:=D300, SP:=D302, P:=8.0,  I:=90.0, D:=1.0, AT:=W0.02 ) → MV:=D310 |

Three instances, three integrators, three derivative histories. Each loop tunes and operates independently. The instance budget cost is real — each PID FB instance consumes roughly 30–60 words depending on the FB declaration — but it is non-negotiable.

Pattern C: Hybrid — Shared Filter, Unique Sequencer

A common pitfall is using the same instance for a first-order lag filter and the sequencer that follows it. The lag filter retains its previous output between scans; the sequencer advances a step counter. Both are multi-scan. Allocate separate instances even when the FB definitions look similar.

Common Traps and Field-Proven Debugging Steps

Trap 1: "PID Output Jumps Randomly"

Symptom: A PID loop's MV occasionally jumps to a value consistent with a neighbouring loop, then drifts back. Likely cause: Two PID FB call sites sharing one instance. Verify by opening the FB instance list in CX-Programmer and confirming each PID rung has a distinct instance name.

Trap 2: "Hour Meter Reads Total of All Motors"

Symptom: An hour-meter FB reports a runtime equal to the sum of all motors' runtimes. Cause: A single instance with a single ACC register counting every time any motor contact closes. The integrator has no notion of which motor triggered it.

Trap 3: "FB Not Working At All"

Symptom: An FB appears to execute (its rung is energised) but outputs never update. First diagnostic: confirm the instance is unique. If two rungs share an instance and one writes the output while the other reads it, the read happens before the write in the same scan on certain rung-ordering configurations. Allocate a unique instance and re-test.

Trap 4: "Compile Error: Instance Area Overflow"

Symptom: CX-Programmer rejects the project with an instance-area overflow error. Cause: Total instance footprint exceeds the CPU's Instance Area. Resolution options: (a) reduce the number of FB call sites, (b) consolidate purely combinational FBs to a shared instance, (c) upgrade to a higher-tier CPU with a larger instance budget, or (d) re-declare non-retentive internal variables to drop them from the retentive allocation.

Trap 5: Retentive vs Non-Retentive Variables

An FB declared with non-retentive internal variables still retains its values during normal scans — it just does not survive a power cycle. Sharing a non-retentive instance across multi-scan FBs is still incorrect. The retentive attribute is independent of the single-scan / multi-scan rule.

Cross-Platform Notes: Siemens and AutomationDirect FBs

The single-instance-versus-unique-instance decision is not unique to Omron. IEC 61131-3 FBs in other vendors follow the same semantic rule, though the naming conventions and instance-management UIs differ.

Siemens STEP 7 / TIA Portal

In STEP 7 and TIA Portal, an FB stores its parameters in an Instance Data Block (IDB). Two calls to the same FB with two separate IDBs (IDB_Motor1, IDB_Motor2) yield two independent instances. Sharing one IDB across two call sites is functionally identical to the Omron shared-instance anti-pattern. See the TIA Portal reference on Function Blocks (FB) in STEP 7 for the canonical definition of FB instance data blocks.

Siemens multi-instance capability (one FB calling other FBs and accumulating their instances in its own IDB) is a related but distinct mechanism: it lets a parent FB own its children's instance memory, which is useful for modular machine code but does not change the rule that each child invocation needs its own working data.

AutomationDirect Productivity Suite / Do-More

AutomationDirect's user-defined Function Blocks (UDFBs) in the Do-More Designer follow the same instance model. Creating a UDFB and dragging it onto a ladder rung creates a new instance by default. The platform does allow the same instance tag to be referenced from multiple rungs; the same single-scan/multi-scan rule applies. The procedure for creating a UDFB is documented in the AutomationDirect Help: Creating a User Function Block (LP306A).

Verification Procedure Before Commissioning

Run the following checklist on every project that uses FBs before connecting to a live process.

  1. Inventory FB definitions. List every FB defined in the project, classifying each as single-scan or multi-scan.
  2. Inventory call sites. For each FB, list every ladder rung or ST section that calls it.
  3. Audit instance allocation. For multi-scan FBs, confirm one unique instance per call site. For single-scan FBs, confirm that instances are intentionally reused (and not duplicated by accident during copy-paste).
  4. Check instance budget. Compile the project and read the instance count vs the budget for the connected CPU. Confirm headroom of at least 10–15% for future modifications.
  5. Simulate multi-scan FBs. Force the inputs of two same-instance PID loops and observe the integrator state in online mode. If state is shared, the bug is exposed immediately.
  6. Test power-cycle retentivity. For loops that must retain set points, integrator bias, or step counter across a power cycle, verify the instance's retentive declaration matches the requirement.
  7. Document the instance map. Export the instance list and bind it to the P&ID or functional specification. This is the document that protects the next programmer from inadvertent shared-instance mistakes during maintenance.

Memory-Math Sanity Check

For a rough sizing estimate, the instance footprint of an FB scales roughly with the number of declared variables. Suppose a PID FB declares 20 variables at 16 bits each: 20 × 2 bytes = 40 bytes per instance. Ten PID loops consume 400 bytes. The CJ1W-CPU43's Instance Area is documented in the operation manual; the relevant figure to confirm is whether 400 bytes plus all other FB instances fits within that area. When the budget is tight, profile each FB with CX-Programmer's cross-reference tool to read its actual compiled footprint rather than relying on a rough count.

FAQ

How many FB instances does a CJ1W-CPU43 support?

The CJ1W-CPU43 baseline instance budget is 128 instances, but the actual limit depends on the FB Instance Area allocation and the compiled footprint of each FB. Higher-tier CJ-series CPUs support proportionally more. Always read the connected CPU's instance report in CX-Programmer after compiling to confirm the available headroom.

Can I reuse a single PID FB instance for two temperature control loops?

No. A PID FB retains integrator and derivative state between scans. Sharing one instance across two loops causes each loop's integrator to be overwritten by the other loop's scan, producing unstable or biased MV output. Allocate one unique instance per PID loop — PID_ZONE1, PID_ZONE2, and so on — never share.

Which FBs are safe to share with a single instance?

FBs whose outputs are computed strictly from current inputs within one scan and that retain no internal state. Typical examples are analogue scaling, unit conversion, linearisation, and combinational alarm logic. If the FB contains a timer, counter, accumulator, filter, or any variable that is read in one scan and written in a later scan, it must have a unique instance.

How do I detect a shared-instance bug in a running program?

Open the FB online in CX-Programmer, monitor its internal variables across multiple scans, and check whether values written by one call site appear at another call site. For PID loops specifically, force the PV of one loop and observe whether the integrator state changes during the other loop's execution. If it does, the instances are shared and must be split.

Does the FB instance limit vary with the CJ-series CPU model?

Yes. The instance budget is a function of the CPU model's user-memory partitioning and scales upward across the CJ1M, CJ1G, and CJ1H families. The exact budget must be confirmed against the specific CPU's operation manual and against CX-Programmer's compile-time resource report for the connected controller.

Back to blog