# Tag Usage

Source: https://rungs.dev/docs/tags/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 [#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** `DINT` or `REAL`
- A setpoint or running total → **Local** `DINT` or `REAL`
- A `TIMER`, `COUNTER`, `FBD_TIMER`, or `FBD_COUNTER` the 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 [#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
  declared `DINT[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 [#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 [#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, `EnableIn` and `EnableOut` are 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 [#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.

> **IDEA**
>
> **Practice**
>
> See tag usage in the [Start/Stop Motor exercise](https://rungs.dev/exercises/start-stop-motor) — Input, Output, and Local tags working together.