reference · South Africa
IEC Function Block vs Function: State, Calls and Tests
IEC function block vs function explained for learners: compare state, instance data, repeated calls, reset behaviour and a checked rolling-average example.

The IEC function block vs function distinction is mainly about how reusable logic handles data between executions. A function is a natural choice for a calculation whose result is determined by its supplied inputs. A function block provides an instance through which a particular use of the logic can maintain its own state. The practical design question is: who owns the information that must survive from one call to the next?
For a South African PLC learner, this matters when moving from a single exercise to several pumps, measurements or sequences. Copying code is not the same as creating independent state. Equally, choosing a function does not prevent a larger program from keeping history outside that function. You need to inspect the platform's rules and the actual data flow.
This site has a commercial connection to PLC Simulator. Its educational practice does not supply vendor engineering licences or guarantee execution of arbitrary native function-block code. The illustrations are conceptual study scenes, not vendor software screenshots or evidence of a production installation.
Function versus function block: the practical difference
| Design question | Function-oriented approach | Function-block-oriented approach |
|---|---|---|
| Where is previous history stored? | Outside a deliberately stateless calculation | In the relevant instance, where designed that way |
| What identifies separate equipment? | Separate arguments and caller-owned data | Separate instance data and appropriate arguments |
| What is an easy first example? | Convert a supplied value using a supplied formula | Update a rolling history when a new sample is accepted |
| What must the reviewer inspect? | Inputs, result, side effects and external data access | Inputs, outputs, instance state and execution conditions |
| Does the name prove restart behaviour? | No; inspect the storage actually used | No; between-call memory is not a power-loss guarantee |
This table describes useful design choices. Vendor terminology and language features still matter. Siemens commonly uses FC and FB; CODESYS identifies function POUs as FUN and function blocks as FB. Rockwell Add-On Instructions have their own definition, instance and execution rules. Avoid presenting one short syntax example as code that every environment will accept unchanged.
A stateless calculation has an explicit contract
Imagine a calculation that receives three numbers and returns their arithmetic mean. Its requirement is simple: add the three supplied values and divide by three using an appropriate numeric representation. It does not decide where those values came from or which reading is the newest. If the caller supplies 3, 6 and 12, the expected mathematical result is 7.
A deliberately pure version does not read a hidden global setpoint, modify a shared history or consult an earlier invocation. That makes it easier to test: write the arguments and expected result, then repeat the call in a different order among other tests. Another calculation should not change the result for the same arguments.
The CODESYS function reference describes functions without saved internal status and documents a same-input, same-result rule. It also makes clear that the returned data element can be a structure or array and that additional outputs are possible. “A function always returns only one scalar” is therefore an inadequate general explanation.
Siemens' STEP 7 FC reference says FCs have no own memory for retaining block parameter values, but can use global DBs for permanent data. Consequently, an FC label alone does not prove that a Siemens calculation is free of external state or side effects. Inspect what the implementation reads and writes.

A function block separates the definition from the instance
A function-block definition describes reusable behaviour and its declared data. An instance supplies the state for a particular use. Two measurements can use one definition while keeping separate histories, provided their instance storage and external connections are independent as intended.
The CODESYS function-block reference explains that output and internal values remain between executions and that calls operate through an instance. Its examples also show reading an output after the call. There is no universal rule that a newly calculated output becomes readable only on the next PLC scan.
In STEP 7, a single instance can use its own DB, while a multi-instance can store its data inside another FB's instance. Siemens explains these arrangements in basics of instances. Nesting does not mean that every nested device shares one undifferentiated state variable. Identify the actual storage assigned to each nested instance.
For a code review, draw one box for the reusable definition and separate boxes for the data associated with each logical device. Then add any shared global data or parameters passed by reference. If both instances write the same external history, separate instance names alone will not give you complete independence.
Worked example: a three-sample rolling average
Consider a fictional training requirement for a measurement history. Accept one supplied sample whenever the exercise explicitly calls for an accepted update. Keep the most recent three accepted samples. After each update, report their arithmetic mean. During startup, divide by the number of samples actually stored, not by three with invented zero readings.
This is a mathematical learning model. It does not prescribe an analogue input filter, a sampling interval or a native vendor instruction. The examples use exact arithmetic to establish expectations; an implementation using floating-point values needs a suitable comparison tolerance.
Start with an empty history. Feed the accepted samples 3, 6, 12, 9 and 0 in that order. The zero in the final row is a valid measurement in this fictional requirement, not a marker for bad quality.
| Accepted update | New sample | History after update, oldest first | Sample count | Expected mean |
|---|---|---|---|---|
| 1 | 3 | 3 | 1 | 3 |
| 2 | 6 | 3, 6 | 2 | 4.5 |
| 3 | 12 | 3, 6, 12 | 3 | 7 |
| 4 | 9 | 6, 12, 9 | 3 | 9 |
| 5 | 0 | 12, 9, 0 | 3 | 7 |
At update 4, the oldest value, 3, leaves the window. The sum becomes 27 and the mean becomes 9. At update 5, the 6 leaves and the valid zero enters, giving a sum of 21 and a mean of 7. A program that continues dividing a lifetime sum by the lifetime count would implement a different requirement.
There are two reasonable architectural approaches. A function block can own the window, count and update operation. Alternatively, the caller can own the window and pass its current contents to a stateless averaging function. The latter still supports a stateful application; the state simply lives outside the calculation. Calling an external-state design “impossible because it uses a function” would be wrong.
Write down which component removes the oldest sample, which validates the new sample and which calculates the denominator. If ownership is split between caller and block, define the interface carefully enough that an update cannot be accidentally performed twice. For numeric representation and engineering-unit context, see our analogue scaling and resolution guide.

Startup, invalid samples and reset need separate rules
Before the first accepted sample, the mean is undefined for this exercise. Report an unavailable result with a valid-sample count of zero, rather than silently presenting zero as a measured average. If a platform requires a numeric output field, provide a separate validity indication and document how consumers should use it.
Now insert an invalid sample after update 5. Our chosen rule is to reject that sample without changing the stored window. The retained numeric mean remains 7, but a separate accepted-update indication is false. This means “the previous accepted history is unchanged”; it does not mean that a fresh valid measurement has just arrived.
A consumer may also need age or timestamp information. Three accepted samples could span three regularly timed updates or a much longer period containing rejected readings. This example is sample-based, not a time-weighted average. Do not describe it as a three-second average unless a separate sampling contract establishes that relationship.
Define reset as a separate action that empties the history and clears the valid-sample count. After reset, accepting 30 produces a count of one and a mean of 30. It must not average 30 with the old 9 and 0. If reset and acceptance can arrive together in a real design, specify their priority explicitly; the worked sequence here applies reset first and a new acceptance afterwards.
These questions turn a short formula into a useful reusable component. They also make assessment more meaningful. An instructor can ask the learner to explain why an invalid input is different from a valid zero, or why the first result must not be divided by a full three-sample window.
Separate histories and repeated calls
Give measurement A the sequence in the table and measurement B the sequence 30, 60, 120, 90 and 0. With independent histories, B's means are 30, 45, 70, 90 and 70. Updating A must not silently insert a sample into B's window. Resetting A must not erase B's accepted readings.
A repeated call to the same instance is not automatically forbidden. It acts on the same instance data again, according to the block's semantics. In our model, deliberately accepting 3 and then 6 through one instance produces two stored samples and a mean of 4.5. That could be correct if the requirement genuinely contains two accepted samples.
It becomes a defect if the designer intended one update per cycle but two execution paths both accept the same reading. Likewise, two separate instruments should not accidentally feed a single history. The right question is whether instance sharing and call frequency match the requirement, rather than whether a call site has appeared more than once in the project.
Document the intended number of accepted updates, the conditions that trigger them and the owner of that scheduling decision. If several tasks can access the component, review the target's execution and data-sharing rules. The sequential paper model does not establish that a shared implementation is safe under overlapping access.
Call order affects which result you observe
Suppose the current mean is 7 and the next accepted sample will make it 9. A statement that reads the result before the update sees the existing 7. A statement after the completed update can see the new 9 in this sequential model. It is the order of operations that explains the difference.
This is more precise than saying that every dotted FB output is one scan old. Check where the call occurs, whether it actually executes and which instance the consumer reads. A skipped call, an early return or a consumer observing another instance can each create a different symptom.
For a review exercise, write the intended read-update-read sequence and predict both observations. Then move the consumer deliberately and explain the changed result. Our PLC scan-cycle guide provides broader context for execution and observation; the scheduling details of the actual controller still need checking.

FB memory is not automatically retentive memory
Keeping a value between ordinary calls is a different requirement from preserving it through a restart, download or loss of power. A function block can provide the first while its data is reinitialised under particular lifecycle events. Name each event you need to handle instead of using “persistent” loosely.
CODESYS documents warm-reset retention and different behaviour for cold reset, origin reset and download in its retain-variable guide. It also explains the importance of target support for uncontrolled power interruption. These are platform and storage conditions, not a guarantee supplied by the letters FB.
For the rolling average, decide whether restoring an old history after a restart is even desirable. The samples may refer to conditions that no longer apply. One design might clear the history and wait for fresh readings; another may restore it with an explicit age and validity policy. The application requirement determines the choice.
In South African training, a power-interruption exercise should therefore distinguish normal execution, a controlled restart and loss of supply. Ask which events the training environment can actually reproduce and which target documentation supports the expected state. Do not claim that a browser exercise proves the non-volatile behaviour of an industrial controller.
Siemens FC/FB and Rockwell AOI are not interchangeable labels
For Siemens, inspect the FC or FB interface, any instance DB and any global data used. A calculation written in an FC may be easy to test independently when its inputs and outputs are explicit. An FB can make ownership of a repeated component's state easier to follow. Neither choice excuses hidden shared writes or unclear startup rules.
For Rockwell, an AOI call uses an instance-data argument even when a particular definition has no user-created local tags. The Rockwell AOI usage documentation also distinguishes input, output and InOut parameter behaviour. An empty local-tag list does not transform an AOI into a generic Siemens FC.
Review the instruction's execution modes as part of the comparison. Rockwell's Add-On Instructions manual documents optional scan-mode routines, including prescan and EnableInFalse behaviour. Consequently, transplanting assumptions about an ordinary function call into every AOI execution context can produce the wrong expectation.
When moving a design between environments, carry over the written requirement and expected cases first. Recreate the implementation using the destination platform's types, parameter passing and lifecycle rules. Our TIA Portal versus Studio 5000 workflow comparison covers the surrounding engineering tasks. It does not promise automatic conversion of reusable logic.

What to test before putting a block in a library
Use a short requirement table to organise the test cases. For the average example, include the empty history, one accepted sample, a partially filled window, replacement of the oldest sample, a valid zero, a rejected sample and reset. Add independent instances and deliberately repeated updates. Each case should have an expected result written before execution.
For numeric tests, distinguish mathematical expectations from a controller's representation. Establish the chosen type, allowed input range and rounding behaviour. Avoid allowing a wide tolerance to hide an incorrect denominator or an extra update. A tiny rounding difference and a wrong stored window are different defects.
Also test integration assumptions. Can the caller see whether an update was accepted? Does a consumer check validity? Is there a single owner for reset? Does the call path match the documented sampling rule? A block that passes isolated arithmetic tests can still be connected incorrectly in the wider application.
Save the definition version, test inputs, observed outputs and environment details with the result. If the definition changes, identify which tests must be repeated and which users of the library are affected. Copying a revised block into a project is not evidence that every existing instance has been checked.
PLC program testing practice can help build the habit of predicting results and recording failures. Use the vendor environment when your objective is to verify its specific FB, FC or AOI implementation. The mathematical checks accompanying this guide verify the fictional model, not compiled controller code.
Questions for a South African PLC course provider
Ask whether the course teaches reusable logic by having learners build and test separate instances. A slide defining FC and FB is a starting point; an assessment should reveal whether a learner can locate state, explain a reset and diagnose an accidental shared reference.
For a TIA Portal, CODESYS or Studio 5000 course, request the actual software version, target and learner access arrangements. Clarify whether you will create native code yourself, observe an instructor demonstration or practise general concepts in an educational simulator. These are different learning activities and should be described clearly in the quotation.
A useful portfolio task can be completed without inventing production results: state the fictional requirement, record the environment, show expected and observed histories, and explain one defect you corrected. Label simulated evidence as simulated. Do not present a classroom average calculation as proof of commissioning experience or a formally recognised qualification.
The PLC Structured Text learning tools are a relevant starting point for practising textual logic. Confirm the supported exercise before assuming an arbitrary native declaration can be pasted and executed. Progress from readable requirements to controlled tests, then to the exact engineering environment your course or work requires.
Common questions about functions and function blocks
Can a function control a motor?
A function can participate in control logic, including calculating a command from supplied state and inputs. If the behaviour requires history, that history must have an explicit owner somewhere. An FB is one way to package it; caller-owned state is another. A safety function requires its own appropriate engineering and validation beyond this architectural choice.
Does every FB call need a different instance?
Different logical devices often need independent instances, but repeated calls to the same instance can be intentional. Review the documented behaviour, call order and shared state. Accidental reuse can mix histories; deliberate reuse is not inherently a compiler or architectural error.
Is an FB the same thing as Function Block Diagram?
No. A function block is a reusable program organisation concept with an instance. Function Block Diagram is a graphical programming language. Do not confuse the language used to express logic with the way reusable state is packaged.
Why does my block show an old output?
Check whether the intended instance executed, whether its inputs were accepted and whether the consumer read before or after the update. Also check any validity indication. A retained previous value can be correct under a rejected-input rule while still being unsuitable to present as a fresh measurement.
Will an FB remember its state after a power failure?
Not merely because it is an FB. Check the variable declarations, target storage support and the particular restart or download event. Define whether restored history is useful and valid for the application before choosing a retention mechanism.

A reviewable result has clear data ownership
Finish the exercise by identifying the owner of the history, update trigger, validity information and reset action. Show the five expected averages and demonstrate that two independent measurements remain independent. Explain what happens before the first sample and after a rejected reading.
Those details make the difference between recognising the terms FC and FB and being able to use reusable logic responsibly. They also give a reviewer enough information to distinguish a mathematical error, a scheduling error and a state-sharing error without guessing what the original programmer intended.