Tag Usage
Every rungs.dev tag has a usage — Input, Output, InOut, or Local — that controls where its value comes from, where it appears in the editor, and whether logic can write to it.
Every tag declares a usage that says where its value comes from. Usage controls where the tag appears in the editor and whether the program can write to it.
| Usage | Meaning |
|---|---|
| Input | Value passed into the AOI. Read-only inside the AOI. |
| Output | Value set by the AOI and returned to the caller. |
| InOut | Passed by reference from the caller. |
| Local | Private internal memory used only inside the AOI. |
Choosing a usage
- A pushbutton or limit switch → Input
BOOL - A motor contactor or pilot light → Output
BOOL - A sensor reading a real-world value → Input
DINTorREAL - A setpoint or running total → Local
DINTorREAL - A
TIMER,COUNTER,FBD_TIMER, orFBD_COUNTERthe instruction owns → Local - An array or a structure owned outside the instruction → InOut
Input and Output are always single values. An array or a structure can only be Local — private to the instruction, invisible to everything else — or InOut, which points at a tag that lives outside it.
InOut parameters
Your instruction does not run on its own. Something else — a program, or another instruction — runs it and hands it values. That something is the caller, and the tags it passes in belong to it, not to you.
An Input or an Output is a copy of one of those tags. The instruction gets its own copy when it is called, and the caller gets one back at the end. Think of an Input as a photocopy and an InOut as the original: writing to an Input changes the instruction's copy, writing to an InOut changes the caller's tag.
A copy is fine for one number. It is no use when the caller has to hand over something bigger — a table of recipe values, a buffer of samples — or something the caller goes on using itself, like a timer the surrounding program also reads.
| Input | Output | InOut | |
|---|---|---|---|
| Where the value lives | inside the instruction | inside the instruction | in the caller's tag |
| Has a default value | yes | yes | no |
| Can be an array | no | no | yes |
Can be a structure (TIMER, COUNTER, …) | no | no | yes |
| Must be supplied at the call | no | no | yes, always |
Every row follows from the first. The caller owns the value, so there is no Default Value to set — the Tags table shows a dash — and nothing to fall back on if the call leaves it out, so it must always be supplied. Arrays and structures are things you hand over rather than copy, so only an InOut can be one. A Local can be an array or a structure too, but a Local belongs to the instruction: nothing outside it can see or supply one.
Whatever calls your instruction has to supply every InOut — there is no default to fall back on. What it supplies is always a whole tag of the same type, never a literal, and for an array it must hold the same element type and be the same size or larger.
Studio runs one instruction on its own and cannot call another, so it stands in for the
calling program itself: it allocates a tag of the shape you declared and hands it over every
scan. Name one Ref_ — Ref_Buf, Ref_Tmr — so a reader knows it belongs to someone else
before they write to it.
Two limits:
- One instruction can have 64 InOut parameters at most. That is the same limit a real controller sets.
- Keep the index inside the array. A number that is too big —
Ref_Buf[9]when you declaredDINT[4]— is caught when the routine compiles. When the index is a tag, nobody knows its value until the program runs, so the check happens then: if it points past the end of the array the caller handed you, the scan stops with an error, the same as on a real controller.
Reading vs writing
Coils and math instructions write to tags, which means they require Output, Local or InOut usage. Trying to drive an Input tag from logic produces a compile-time diagnostic:
Operand 'Cmd_Reset' is an input parameter and should not be modified
If you need to drive a value from logic, create an Output, Local or InOut tag — do not mark it Input. An InOut marked Constant is read-only to logic too.
In the Studio editor
- I/O Panel — Input and InOut parameters can be modified at runtime, because both are values the caller supplies and Studio stands in for the caller. Output and Local tags are read-only in the panel.
- Trend — Local tags,
EnableInandEnableOutare not plotted, and neither are arrays or structures, which have no single number to draw. Use a scalar Input, Output or InOut.
EnableIn and EnableOut
Every instruction you write already has two tags you did not create: EnableIn and EnableOut. They are system parameters — parameters the system gives you, rather than ones you declare. They are always the first two rows of the Tags table, they are greyed out, and you cannot rename, retype or delete them. Real Logix Designer® works the same way.
| Tag | Usage | Starts at | What it means |
|---|---|---|---|
EnableIn | Input | 1 | Whether your logic runs on this scan |
EnableOut | Output | 0 | Whether your logic ran, so the next instruction can see it |
EnableIn starts at 1, so your logic runs by default — you never have to switch it on. At the start of every scan EnableOut is set to whatever EnableIn is, and then your logic runs.
When EnableIn is 0 your Logic routine does not run. EnableOut goes to 0 and your outputs keep the values they last had.
EnableIn comes from whatever calls your instruction, so nothing in Studio sets it: the I/O Panel does not list it, and its row in the Tags table is read-only. In Studio your logic always runs.
Practice
See tag usage in the Start/Stop Motor exercise — Input, Output, and Local tags working together.
Data Types
Reference for tag data types in rungs.dev — BOOL, SINT, INT, DINT, REAL, TIMER, COUNTER, CONTROL, FBD_TIMER, FBD_COUNTER, FBD_ONESHOT — what each holds and which instructions read or write it.
Array Tags
Use array tags in rungs.dev to store lists of BOOL, DINT, REAL, TIMER, COUNTER, FBD_TIMER, or FBD_COUNTER values under one name and reference elements with Tag[index].