Skip to main content
Call Eric:863-698-8266
CURRYCONTROLS.COMControls & Automation Knowledge Hub
ReferencePLCProgrammingDocumentationDesignEngineering

Program Organization

Structuring a controller program so that someone else can maintain it: a layout that follows the plant, one routine per job, standard device blocks, I/O mapped in one place, a fixed execution order, naming that means something, and comments that say why.

10 min readUpdated Sep 5, 2026Published Sep 5, 2026By Eric Sullivan

The short answer

Program Organization

A well-organized controller program mirrors the plant: a main routine that calls the others in a fixed order, an input mapping routine that copies physical inputs to named tags, a routine per process area or piece of equipment built from standard device blocks, separate routines for alarms and communications, control loops in a periodic task at a fixed rate, and an output mapping routine at the end. Tags are named by equipment and attribute, setpoints live in named registers rather than as constants, every rung or block has a comment that says what it is for, and a revision record inside the program says what changed and when. The test is whether a technician who has never seen the program can find the logic for one pump in under a minute.

Key points

  • Structure follows the plant: area, then equipment, then device. Nobody should have to search a 3,000-rung routine.
  • Map physical I/O to named tags in one routine at the start and one at the end; the logic never touches an address.
  • Standard device blocks for pumps, valves, and analyzers; every pump behaves the same and is configured, not programmed.
  • Fixed execution order: inputs, logic, alarms, communications, outputs. A tag written after it is read costs a scan.
  • Setpoints in named registers with limits, never constants in the code.
  • Comments say why, tag descriptions say what, and a revision record inside the program says what changed.

The test

Hand the program to a technician who has never seen it, and ask them to find why pump 2 is not starting. If they open the program tree, see a routine named for the lift station, open it, find pump 2, and read a permissive list, the program is organized. If they scroll through one enormous routine searching for the output tag, it is not. Organization is not tidiness for its own sake; it is the property that makes a control system maintainable by someone other than the person who wrote it.

The vocabulary by platform

ConceptIEC 61131-3Rockwell LogixSchneider Control ExpertSiemens TIA Portal
Scheduling unitTaskTask (continuous, periodic, event)Task (MAST, FAST, event)Organization block (OB)
Container of logicProgramProgram with routinesSectionFunction (FC) or function block (FB)
Reusable block with memoryFunction blockAdd-On InstructionDerived function block (DFB)Function block with instance data block
Reusable block without memoryFunctionAdd-On Instruction without stateElementary functionFunction (FC)
Structured data typeStructureUser-defined type (UDT)Derived data type (DDT)PLC data type (UDT)
Global dataGlobal variablesController tagsUnlocated variablesGlobal data block (DB)
Different names for the same organizational tools

A layout that works

Routine or sectionPurposeNotes
MainCalls every other routine in a fixed orderNothing else; a reader sees the whole program flow on one page
FirstScanInitialization after power up or downloadSequence recovery, default setpoints if lost, communication resets
Inputs_MapCopy physical inputs to named tags; scale analog inputsThe only place physical input addresses appear
Area routinesOne per process area: LiftStation, Filters, Chemical, DisinfectionEach built from device blocks; pump 2 lives in its area routine
LoopsPID and other continuous controlIn a periodic task at a fixed rate; never in the continuous task
AlarmsAlarm conditions, delays, and acknowledgment handlingEvery alarm in one place, in the order of the alarm list
CommsMessages to other controllers and devices, with status handlingCommunication status bits feed signal validation in the area routines
HMIHandshakes, command pulses, and the tags the HMI writesCommands from the HMI are consumed and cleared here
Outputs_MapCopy named output tags to physical outputsThe only place physical output addresses appear
DiagnosticsModule status, scan time, battery, redundancyFeeds the controller health alarms

Mapping I/O

The logic reads a tag named for the device, not a channel address. An input mapping routine at the start of the scan copies each physical input to its named tag and scales the analog ones; an output mapping routine at the end copies the named output tags to the physical channels. The cost is a few dozen rungs. The return is that a failed input card can be replaced by a spare in another slot by editing one routine, the program can be tested in simulation by disabling the mapping, and every rung in the logic reads in plain language.

Standard device blocks

A plant has twelve pumps that all need the same things: a run command, running feedback, a fail-to-start timer, a fail-while-running check, run hours, start counts, permissives, interlocks, HOA handling, and an HMI faceplate. Written twelve times, the twelve copies drift apart until no two pumps behave alike. Written once as a device block and instanced twelve times, every pump behaves the same, a fix applies to all of them, and a new pump is an instance with a configuration. The same applies to valves, analyzers, and drives. The block interface becomes the vocabulary of the whole system: every pump has a Sts.Running, a Cmd.Start, and an Alm.FailToStart, and the HMI faceplate binds to them by name.

Execution order

The controller executes the routines in the order the main routine calls them, once per scan. If the alarm routine reads a tag that the area routine writes, and the alarm routine runs first, the alarm sees the value from the previous scan. One scan late rarely matters, but a chain of such dependencies can add several scans of delay to a sequence and produce behavior that is hard to reproduce. Call the routines in the order data flows: inputs, area logic, loops, alarms, communications, HMI, outputs. And write each output from exactly one place; two rungs writing the same coil is the classic error, and the last one wins silently.

Naming

A tag name says what equipment and what attribute: P_101_Run, LT_101_PV, FV_102_ZSO. Where the platform supports structures, the device tag is the structure and the attribute is the member: P_101.Sts.Running. Use the tag numbers from the drawings and the instrument list, so the field, the drawings, the program, and the HMI all use the same identifiers. Descriptions carry the words: Lift Station 1 Pump 1 Running. Setpoints are named tags with engineering units and limits, editable from the HMI: LS1_LeadStartLevel_ft, not a constant 8.5 in a compare instruction.

Comments and revisions

A tag description says what a tag is. A rung or block comment says why the logic is the way it is: Delay is 15 s because the check valve slams if the pump stops with the discharge valve open. The reader can see what the rung does; the comment explains the intent, which is the thing that is lost when the author leaves. Keep a revision record inside the program, in a comment or a dedicated routine: date, who, what changed, and why, and export the project file to version control at every change so the history exists somewhere other than the laptop.

Signs of a program that needs reorganizing

  • One routine of thousands of rungs, or routines named Routine1 through Routine9.
  • The same pump logic copied per pump with small, undocumented differences.
  • Physical input and output addresses scattered through the logic.
  • Constants in compare and math instructions where setpoints should be.
  • Outputs written from more than one rung.
  • No comments, or comments that restate the instruction: Turn on output.
  • No record of what changed since the last time anyone looked.

Frequently asked questions

How big should a routine be?
Small enough to read in one sitting and to describe in one sentence: this routine runs the filters. A routine that needs a table of contents is two routines. On most projects that is a few dozen to a couple of hundred rungs, and a device block instance counts as one rung.
Are device blocks worth it on a small system?
Yes, on anything with more than one pump. The block takes longer to write the first time than a few rungs of logic, and it pays back on the second pump, on the HMI faceplate that binds by name, and on every future change. Small systems grow.
Should loops really be in a periodic task?
Yes. A PID computes with an assumed sample time; in a continuous task that time varies with scan length and the loop tuning changes with it. A periodic task at 100 to 500 ms gives the loop a fixed sample time and predictable behavior. The same applies to totalizers and rate calculations.
What is the minimum for a program someone else can maintain?
A main routine that shows the flow, routines named for the plant areas, I/O mapped in one place, tags named from the drawings with descriptions, setpoints as named tags, a comment on every rung whose purpose is not obvious, and a revision record. That is a day of work on a program of any size, and it is the day that saves the most later.

Direct contact

Have a controls question?

Reach Eric Sullivan directly about anything on this site, a controls or automation topic, or one of his personal projects.