TIA Portal Β· Track 04 Β· The Four Block Types

Blocks & the Memory Question

A TIA program isn't one long script β€” it's a stack of blocks that call each other. Four kinds, one question tells them apart.

🧠 β€œDoes it remember anything between scans?”
πŸ“… OB βž— FC 🧠 FB πŸ“¦ DB
4
block types
2
live simulators
πŸŽ“
exam + cert
πŸ“…OB
βž—FC
🧠FB
πŸ“¦DB
01 Β· The cast

Four blocks, one question

Memory is the dividing line. An FC (function) is pure maths β€” give it inputs, get an output, it forgets everything the instant it returns. An FB (function block) gets a private instance DB to remember state across scans. An OB is where the OS calls in. A DB is just data.

πŸ“…
OB
Organization Block
The entry points the operating system calls β€” OB1, the interrupts. Your program starts here.
βœ“ remembers via DBs
βž—
FC
Function
Inputs in, result out β€” like sqrt(). No private memory; forgets between calls.
βœ— forgets everything
🧠
FB
Function Block
Behaviour plus a private instance DB, so it can hold timers, counters, states.
βœ“ has instance DB
πŸ“¦
DB
Data Block
Pure data β€” recipes, setpoints, an FB's instance. No logic, just storage.
βœ“ IS the memory
02 Β· Memory, made visible

The FC forgets. The FB remembers.

Here OB1 calls two blocks every scan, both trying to count a pump's run-hours. FC_Hours is a plain function β€” its working number is a temp that's wiped after every call, so it can never accumulate. FB_Pump has an instance DB, so its total survives scan after scan. Run the pump and watch only one meter climb.

βž— FC_Hours Β· called by OB1, no instance
"Add this scan's time to #runHours." But #runHours is a temp β€” born at 0 every call.
πŸ›’οΈ
0.0 h
total run-hours (FC)
#runHours (TEMP)value
at call start0.000
at call end0.000
after returnβ€” wiped β€”
🧠 FB_Pump · instance "Pump_1" (DB30)
Same line of code β€” but #runHours is a static var in the instance DB, so it persists.
πŸ›’οΈ
0.0 h
total run-hours (FB)
"Pump_1".runHours (STATIC)value
last scan0.000
this scan0.000
kept for next scanβœ“ retained
scan #0

That's the whole reason FBs exist. Anything that must remember β€” a timer, a counter, a step number, a state machine β€” needs an FB and its instance DB. Pure, stateless calculations can stay in an FC.

03 Β· Reuse

Write once, instance many

The payoff: write FB_Pump once, then call it for every pump on the site. Each call names its own instance DB β€” same behaviour, separate memory. Fix a bug in the FB and all of them inherit it; yet Pump_1's hours never bleed into Pump_2's.

FUNCTION_BLOCK "FB_Pump"
  VAR running:Bool; runHours:Real; END_VAR   // VAR = static = remembered

// call it three times β€” three private instance DBs:
"Pump_1"(running := %I0.0);   // DB30
"Pump_2"(running := %I0.1);   // DB31
"Pump_3"(running := %I0.2);   // DB32

One block of code, three notebooks. This is the same idea you met as instance DBs in the Execution Model lesson β€” here's why it's the backbone of every real Siemens project.

04 Β· The scan, block by block

Watch one scan walk the call tree

Blocks don't run in isolation β€” they call each other, and the OS only ever calls the OB. Press Run one scan and follow the execution: OB1 calls FC_Scale (which forgets), then FB_Conveyor (which remembers, in its instance DB), which reads a recipe from a global DB. The call-stack and the memory ledger update live β€” so you can see exactly where each value lives and what survives to the next scan.

πŸ“…
OB1
main cyclic β€” the OS entry point
OB
βž—
FC_Scale
scales %IW64 β†’ % Β· stateless
FC
🧠
FB_Conveyor Β· "Conv_1"
TON + step, kept in DB30
FB
πŸ“¦
DB_Recipe
global setpoints Β· read-only here
DB

Memory ledger β€” after each scan

FC_Scale · #scaledTEMP β€” local, every callβ€”
"Conv_1".timer.ETSTATIC β€” in instance DB300.00 s
"Conv_1".stepSTATIC β€” in instance DB301
DB_Recipe.targetSpeedGLOBAL DB β€” persistent data1500 rpm

πŸ”΄ TEMP is wiped at every return Β· 🟒 STATIC lives in the instance DB scan-to-scan Β· 🟑 a global DB persists for the whole program.

call stack β†’
Press Run one scan to step through the call tree.
scan #0

The shape of every TIA program is here: the OS calls an OB, the OB orchestrates FCs and FBs, and they read/write DBs. Logic flows down the tree; data lives in DBs. Master this and "where does this value live?" stops being a mystery.

05 Β· Going deeper

The nuances that separate a pro

"Four block types" is the surface. Here's what actually trips people up in real projects:

πŸ“… OBs are more than OB1

OB100 runs once at startup (init values). OB30–38 are cyclic interrupts firing on a fixed time base β€” perfect for PID that must run at an exact interval, independent of OB1's scan. Hardware-interrupt OBs fire on an input edge; error OBs (OB82/121…) catch faults so the CPU doesn't STOP.

🧠 Multi-instance β€” an FB inside an FB

A TON is itself an FB. When you declare it as a static var inside your FB, its memory nests inside your instance DB β€” no separate DB per timer. That's multi-instance: one tidy instance DB holds your FB's state and all its sub-instances.

πŸ“¦ Optimized vs standard DB

Optimized DBs (S7-1200/1500 default) have no fixed byte addresses β€” the CPU packs them for speed and you access by name only. Standard DBs keep classic %DBx.DBWy offsets for legacy access. Inserting a tag in a standard DB shifts every address below it β€” a classic footgun.

βž— FC β‰  useless β€” it's your library

Because an FC has no instance DB, it's the lightest, cleanest home for stateless work: a scaling routine, a CRC, a unit conversion. No DB clutter, callable anywhere. Reach for an FC when the answer depends only on the inputs β€” and an FB the moment it must remember.

06 Β· Check yourself

Which block?

You need a reusable conveyor controller that holds its own state machine and a TON timer, callable for each of 12 conveyors. What do you build?