# Omron

> Connect Omron PLCs, CJ, CS and CP controllers by memory address over FINS (UDP, TCP, or Host Link on a serial line) and NJ, NX and NY controllers by variable name over EtherNet/IP; the FINS settings, the address forms, the data types, reads, writes and discovery.

The **Omron** driver talks to Omron PLCs in either of their two languages, picked per device. A
CJ, CS or CP controller, and an NJ or NX set to CJ memory mode, is read over FINS by memory
address, written the way Omron's programming software writes it: `D100`, `W0.01`, `CIO100.05`. An
NJ, NX or NY controller is read over EtherNet/IP by the name of a variable it publishes to the
network, such as `Level` or `Motor.Speed`. One station reads both kinds side by side under the one
driver. Add a device under the Omron driver in the [Connector](connector) and pick its
**Protocol**; the panel shows only the fields that protocol uses.

## Protocols {#protocols}

| Protocol | Controllers | Tags are addressed by | Port |
| --- | --- | --- | --- |
| **FINS** | CJ1, CJ2, CS1, CP1 and the other CJ, CS and CP controllers with an Ethernet port or unit; an NJ or NX in CJ memory mode | **Memory address**, such as `D100` or `W0.01` | 9600 by default |
| **NJ/NX tags by name** | NJ, NX and NY controllers, such as NJ501, NJ301, NJ101, NX1P2, NX102, NX502, NX701 and NY5 | **Variable name**, such as `Level` or `Motor.Speed` | none: EtherNet/IP answers on its standard port, 44818 |

FINS is the default, and a new device starts on it. The protocol is a setting of the device, so a
CJ2 and an NX1P2 sit under the same driver, each read in its own language. Switching the protocol
keeps the FINS settings as they were left, for when FINS comes back, and every tag of the device
reads its address in the new protocol from then on: its **Data type** settles to one the address
holds there, and an address the new protocol cannot read is flagged on the tag's page until it is
corrected.

## Connection {#connection}

| Field | Meaning | Default |
| --- | --- | --- |
| **Host** | IP address or host name of the PLC's Ethernet port or unit. | empty |
| **Protocol** | **FINS** or **NJ/NX tags by name**. The line under it says what the protocol in force reads: "Memory areas of CJ, CS and CP controllers, and of an NJ/NX in CJ memory mode." or "Variables an NJ, NX or NY controller publishes to the network, read by name over EtherNet/IP." | FINS |
| **Port** | FINS only: the port the PLC answers FINS on, the same over UDP and over TCP, 1 to 65535. An empty box shows 9600 in grey and the device is dialed on it. A device read by tag name has no port box. | 9600 |
| **Poll interval (ms)** | Device-wide read period for tags that do not override it. | 1,000 |

The device header shows the assembled endpoint. A FINS device writes every one of its settings
into it, a node of 0 standing for automatic, for example
`omron://192.168.250.1:9600?protocol=fins&transport=udp&network=0&node=0&unit=0&source=0&timeoutMs=2000`.
A device read by tag name names only its host and its protocol, `omron://192.168.250.1?protocol=njnx`.
Each tag may set its own **Poll interval (ms)**; a tag value of 0 falls back to the device interval.

## Prepare the controller {#prepare-the-controller}

An NJ, NX or NY controller read by tag name serves only the global variables it publishes to the
network. Publishing is an attribute of each variable, set in Sysmac Studio and transferred to the
controller. A controller read over FINS needs no such setting.

| Setting | Where in Sysmac Studio | Without it |
| --- | --- | --- |
| **Network Publish** set to **Publish Only** (or Input or Output for a variable a tag data link also uses), on every global variable the station reads or writes | **Programming > Data > Global Variables**, the variable's **Network Publish** column. Transfer the project to the controller (**Controller > Synchronize**). | The controller answers that it serves no variable by that name, exactly as for a name that does not exist. The tag reads as bad quality, and the device's other tags keep reading. |

A variable of a program, a local variable, cannot be published: declare it among the global
variables, or copy it into a global variable in the program.

When the controller answers that it serves no variable by a tag's name, the device's page names the
variable and the tags that read it, with both causes (a name that does not exist, or a variable that
is not published) and these steps, in a notice that goes away by itself once the variable reads;
the tag's own page carries the same notice. The journal and the agent read the same steps.

## The FINS card {#the-fins-card}

A device read over FINS carries a **FINS** card under its Connection card: what its requests travel
in, whom they address and how long each one waits for its answer. A device read by tag name has no
such card.

| Field | Meaning | Default |
| --- | --- | --- |
| **Transport protocol** | **UDP**: "One datagram per request, answered to the port it left from: the default of Omron's Ethernet ports." **TCP**: "One connection, in which the PLC assigns this station its FINS node." | UDP |
| **Network** | "The PLC's FINS network: 0 for the network this station is on, 1 to 127 through the PLCs' routing tables." | 0 |
| **PLC node** | The PLC's FINS node, 1 to 254. Empty, the box reads "Automatic": over UDP the last number of the PLC's IP address (a PLC at `192.168.250.1` is node 1), over TCP the node the PLC announces when the connection opens. | Automatic |
| **Unit** | "The unit inside the PLC that answers: 0 for the CPU unit." Up to 255. | 0 |
| **Station node** | UDP only: this station's FINS node, 1 to 254. Empty, the box reads "Automatic": the last number of this station's IP address on the network it reaches the PLC through. Over TCP the box is not drawn, because the PLC assigns the node in the connection. | Automatic |
| **Response timeout (ms)** | "How long a FINS request waits for its answer." 100 to 60,000. | 2,000 |

A number outside its range is refused under the box, for example "Enter a number between 0 and 127.",
and the box goes back to the value in force. Switching the transport to TCP keeps the station node
typed for UDP, which the device then does not use.

## Host Link on a serial line {#host-link-on-a-serial-line}

A CP1E, CP1L, CP1H, CJ or CS controller with only a serial port (RS-232C, or RS-485 and RS-422A
through an option board or a converter) is read over FINS on Host Link, through a serial line of the
Omron driver: one COM port shared by up to 32 PLCs, each answering to its own unit number. Add the
line with **Add line** on the Serial lines table of the driver's page and set its **Serial port**,
**Baud** and **Serial format** to what the PLCs' serial ports are set to (the rest of the line's
page is on [Serial lines](connector-lines)), enable it, then add each PLC with **Add device** on the
line's page.

| Setting | Where | Value |
| --- | --- | --- |
| Port mode | The PLC Setup of the PLC, for the serial port the line is wired to | Host Link |
| Baud and format | The line | As the PLCs' ports are set; a Host Link port leaves the factory on 9600 baud and `7E2` |
| **Unit ID** | The device's Connection card, beside its **Serial line · fixed** | The PLC's Host Link unit number, 0 to 31, as its PLC Setup sets it. A new device takes the first number free on the line; a number another PLC on the line holds is refused |
| **Response timeout (ms)** | The device's FINS card | 100 to 60,000; 2,000 |

A device on a line is read over FINS for good: it has no **Protocol**, **Host** or **Port** box, and
its FINS card shows "FINS over Host Link on this serial line, to the PLC whose unit number (set for its serial port in the PLC Setup) is the Unit ID above." and the **Response timeout (ms)** alone, because the request goes to the CPU unit of
the PLC the bus addresses and no network field applies. It never moves to the network, nor does a
network device move to a line. Its tags are addressed as over the network (`D100`, `W0.01`), and its
endpoint names the line and the unit, for example
`omron://serial/<line id>/COM5/9600/7E2?protocol=fins&transport=hostlink&hostLinkUnit=0&timeoutMs=2000`.

| On a serial line | What happens |
| --- | --- |
| Several PLCs on one line | One request and its answer at a time for the whole line; an answer from another unit, or noise, is passed over |
| A PLC that does not answer within its timeout | That device reconnects; the other PLCs on the line keep reading |
| The PLC takes the frame as damaged and answers a Host Link end code, such as `13 (FCS error)` | The device reconnects |
| The port fails, for example when the adapter is pulled | Every device on the line reconnects; the port is opened again after a pause of 1 second, doubling up to a minute |
| A text tag | At most 534 characters, what one Host Link frame carries |

The scan does not search a serial line: add each PLC by its unit number.

## Addressing {#addressing}

A tag is addressed by one box in its Source card, named after the device's protocol: **Memory
address** over FINS, **Variable name** for a device read by tag name, with the protocol's hint
under it. An address the driver cannot read is refused on the tag's page where it is typed, with
the reason. The Source card's read-only **Source address (wire)** line shows the address the driver
receives.

### Memory addresses (FINS) {#memory-addresses-fins}

A memory address is the area's letters, the word number in decimal and, for a single bit, a dot
and the bit, 00 to 15. Letters are not case sensitive, and the older spellings are read too.

| Area | Examples | Words | Also written |
| --- | --- | --- | --- |
| CIO | `CIO100`, `CIO100.05`, `100.05` | 0 to 6143 | a bare number, which is a CIO address |
| Work (W) | `W0`, `W0.01` | 0 to 511 | `WR` |
| Holding (H) | `H10`, `H10.00` | 0 to 1535 | `HR` |
| Auxiliary (A) | `A100`, `A100.03` | 0 to 1471 | `AR` |
| Data memory (D) | `D100`, `D100.15` | 0 to 32767 | `DM` |
| Extended data memory (E) | `E0_100`, `EA_0`, `E18_0` | 0 to 32767 | the bank in hexadecimal, 0 to 18, between the E and the underscore |

Each area is bounded by the largest that any CJ, CS or CP controller holds (a CJ2 has 1,536
holding words and extended memory banks up to 18). A word or a bank a smaller controller lacks is
that PLC's own answer, an error on the tag's first read (see [Reading](#reading)). What the tag's
page refuses where it is typed:

| You type | The tag's page says |
| --- | --- |
| Something that is not an area, a word and a bit, such as `X100` or `D100.` | "A FINS memory address is the area, the word and, for one bit, a dot and the bit, for example D100, W0.01, CIO100.05, H10, A100 or E0_100." |
| A word past the end of its area, such as `D40000` or `W512` | "That word is past the last word of its area on any CJ, CS or CP controller." |
| A bit past 15, such as `W0.16` | "The bit of a word is numbered from 00 to 15." |
| A bank past 18, such as `E19_0` | "Extended memory banks are numbered from 0 to 18 in hexadecimal." |

The wire address is the address in its one spelling, the bit in two digits: `100.5` travels as
`CIO100.05` and `DM100` as `D100`. A text tag adds the characters it spans after a `?`, so a
16-character text at D200 travels as `D200?16`.

### Variable names (NJ/NX) {#variable-names-njnx}

An NJ, NX or NY controller is read by the name of a global variable it publishes to the network,
which in Sysmac Studio is a variable whose Network Publish attribute is Publish Only, Input or
Output (see [Prepare the controller](#prepare-the-controller)). A variable the controller does not
publish cannot be read by name. A name is written in
ASCII letters, digits and underscores, never starting with a digit, with a dot before the member
of a structure and an index in brackets: `Level`, `Motor.Speed`, `Temps[3]`, `Grid[1,2]`. Any
other shape is refused on the tag's page: "A variable name is written in letters, digits and underscores, not starting with a digit, with a dot before a member and an index in brackets, for example Level, Motor.Speed or Temps[3]."
A name in another script, which Sysmac Studio allows, is refused the same way, because the
EtherNet/IP request cannot carry it.

The controller lists its variables in a way this driver does not read, so every tag of a device
read by tag name is typed by hand. Whether the controller publishes a name is its own answer, given
at the tag's first read. There is no offset field: a member or an element is named for itself, and
an element of a BOOL array is read by its own name, such as `Flags[5]`. The wire address is the
name followed by `?0`, for example `Motor.Speed?0`.

## Data types {#data-types}

Over FINS the **Data type** offered follows the address:

| The address names | Data type | What is read |
| --- | --- | --- |
| A bit, such as `W0.01` | Boolean | That bit alone. |
| A word, such as `D100` | Int16 or UInt16 | The word. |
| A word and the one after it | Int32, UInt32 or Float | Two words, the low word at the address and the high word after it, the way Omron's own instructions keep a double word. The last word of an area starts no pair, so it offers Int16, UInt16 and String alone. |
| A word and the ones after it, as text | String | The **Length (characters, blank = 16)** the tag declares, from 1 to 1998 characters, two to a word with the first in the high byte. The text ends at its first NUL. On a serial line, 1 to 534 characters. |

Typing an address that does not hold the tag's type changes the type to the one the address reads
most naturally: a Boolean for a bit, an Int16 for a word. A type the address does not hold is
refused with the ones it does, for example "The address D100 is read as one of these data types: Int16, UInt16, Int32, UInt32, Float, String."
There is no byte or word order option: FINS keeps every word high byte first, and the driver
handles it.

A device read by tag name offers every atomic type of its controller:

| Data type | Variable type in Sysmac Studio |
| --- | --- |
| Boolean | BOOL |
| SByte | SINT |
| Byte | USINT |
| Int16 | INT |
| UInt16 | UINT |
| Int32 | DINT |
| UInt32 | UDINT |
| Int64 | LINT |
| UInt64 | ULINT |
| Float | REAL |
| Double | LREAL |

A WORD variable is read as UInt16 and a DWORD as UInt32. STRING variables are not read, and String
is not offered. A type outside the list is refused with it: "A variable of an NJ/NX controller is read as one of these data types: Boolean, SByte, Byte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Float, Double."

## Reading {#reading}

Over FINS the device holds one conversation with its PLC and sends one request at a time, each tag
one memory area read of its words, and takes as the answer only the reply that carries that
request's own number, so a late reply is never read as the next one's. Before any tag is read, the
PLC must answer a controller data read, with any end code; the model it names is written to the
journal. What the PLC answers then decides what becomes of each read:

| The PLC answers | The read |
| --- | --- |
| Normal completion | The value. |
| An end code about the point, such as an address the PLC does not have | That tag goes without a value, and its error names the code and its meaning in Omron's manual, for example `end code 0x1103 (address range error)`. Every other tag of the device keeps reading. |
| An end code about the way to the PLC (0x01xx, 0x02xx, 0x03xx, 0x05xx), a relay that timed out on the way, or nothing within the **Response timeout (ms)** | The device reconnects, and its tags fail their reads until the PLC answers again. Each tag's policy for [a device that did not answer](connector-value-pipeline#the-device-did-not-answer) decides what it shows. |

A device read by tag name is proven by asking the controller for a variable no program declares:
the controller's answer that no such name exists is an answer from the controller. Its requests go
through the same EtherNet/IP code as the [Rockwell EtherNet/IP](driver-rockwell) driver's, and time
out after 10 seconds.

## Writes {#writes}

Tags whose **Access** is Read and write or Write only can be written; a new tag starts as Read
only. A write waits its turn on the device's queue with the reads, and sends the value it was asked
for and nothing beside it:

| The tag reads | What the write sends |
| --- | --- |
| A FINS bit (`W0.01`) | That bit alone: the PLC changes it in place and leaves the other bits of the word as they are. |
| A FINS word or double word | The whole value, at the address and, for two words, the word after it. |
| A FINS text | The whole declared length, the text at the front and NULs behind it, so nothing of a longer earlier text is read back after it. A text that does not fit the length is refused, never cut. |
| An NJ/NX variable | The value, to that variable by its name; an element of a BOOL array as that BOOL alone. |

| The PLC answers a FINS write with | The write |
| --- | --- |
| Normal completion | Delivered. |
| An end code that refuses it | Refused, and the reason names the code and its meaning, for example `end code 0x2101 (read-only)`. |
| Nothing within the **Response timeout (ms)**, or a relay that timed out on the way (0x0205) | No response. |

A FINS write whose value the tag's type cannot hold is refused before anything is sent.

## Discovery {#discovery}

The Omron driver's page carries a **Scan scope** card with one optional box, "PLC address for a FINS probe, e.g. 192.168.250.1 (empty = NJ/NX by broadcast only)".
Discover then asks up to two questions, one after the other:

| Question | When | What it offers |
| --- | --- | --- |
| A controller data read over FINS and UDP, every node automatic, sent to the PLC in the box: an IP address or a name, with `:port` when the PLC answers FINS on another port than 9600. The progress line reads "Asking 192.168.250.1 to identify itself over FINS…". | Only when the box holds an address. | The PLC, as a FINS device named by the model it answers with, at `omron://<host>:<port>?protocol=fins&transport=udp&network=0&node=0&unit=0&source=0&timeoutMs=2000`. A PLC that answers nothing offers nothing. |
| The EtherNet/IP identity request, broadcast on every network this computer is on. The progress line names them: "Searching for Omron NJ/NX controllers on 192.168.0.255…". | Every time. The scan listens until 5 seconds pass with no new answer. | Each NJ, NX or NY controller that answers, as a device read by tag name, named by its product name (an NX1P2, for example). An NX I/O coupler, whose product name starts with `NX-`, holds no variables and is passed over, as is any other Omron product. |

Neither question finds tags: a FINS PLC publishes no list of its addresses, and an NJ/NX lists its
variables in a way the driver does not read, so each candidate reads "No tags reported. Add the device to configure tags in its editor."
Something in the box that is not a host is refused under it, and Discover greys: "An Omron scan asks the PLC written here to identify itself over FINS: its IP address or name, optionally with its port (for example 192.168.250.1 or 192.168.250.1:9600). Leave it empty to look only for NJ/NX controllers by broadcast."
A controller on a network this computer is not on does not answer the broadcast; add it by hand.
The Rockwell EtherNet/IP scan hears the same broadcast and leaves every Omron controller to this
one. The rest of the scan's behaviour is on [Discovery](connector-discovery).

## Agent tools {#agent-tools}

`driver_capabilities` describes this driver under `omron`: its two protocols, each with the device
fields, the address forms and the data types it takes, the FINS transports and ranges, writes and
discovery. `device_upsert driver=Omron` takes `omronProtocol` (`Fins` or `NjNx`) and, over FINS,
`finsTransport` (`Udp` or `Tcp`), `finsNetwork`, `finsNode` (0 for automatic), `finsUnit`,
`finsSourceNode` (UDP only, 0 for automatic) and `finsResponseTimeoutMs`; a device read by tag name
takes no port and no FINS field. `tag_upsert` takes the memory address or the variable name as
`address`, the type as `opcUaType` (omitted, a bit takes Boolean and a word Int16), and the length
of a FINS text as `wireQuantity`. `device_discover driver=Omron` runs the scan, with `target` for
the FINS probe. A CJ2 read over UDP and an NX1P2 read by tag name:

```
device_upsert driver=Omron name=Press host=192.168.250.1 omronProtocol=Fins finsTransport=Udp
tag_upsert device=Press name=Level address=D100 opcUaType=Float
device_upsert driver=Omron name=Filler host=192.168.250.2 omronProtocol=NjNx
tag_upsert device=Filler name=Speed address=Motor.Speed opcUaType=Float
```

A PLC on a serial line hangs on a line of this driver: `serial_line_upsert driver=Omron` creates
the line, and `device_upsert driver=Omron serialLineId=<id>` adds the PLC over Host Link
(`finsTransport=HostLink`, which the line implies) with `unitId`, its unit number 0 to 31 (omitted,
the first one free), and `finsResponseTimeoutMs`; the network fields are refused on it. A CP1L at
unit 0 on COM5:

```
serial_line_upsert driver=Omron name=HostLink serialPort=COM5 baudRate=9600 serialFormat=7E2
device_upsert driver=Omron name=Mixer serialLineId=<the line's id> unitId=0
tag_upsert device=Mixer name=Level address=D100 opcUaType=Int16
```

The other tools are on [Agent tools](agent-tools).

## Limits worth knowing {#limits-worth-knowing}

- A controller that speaks only the older C-mode Host Link commands, such as a CPM1, a CPM2, a
  CQM1 or a C200HS, is not read, on a [serial line](#host-link-on-a-serial-line) or through a
  converter: the driver sends FINS commands only.
- Timers and counters are not offered over FINS: their present value is kept in BCD or in binary
  depending on how the PLC is set up, and nothing in a FINS answer says which. Read such a value
  through a word the program copies it into.
- The variables of an NJ/NX controller are never listed, neither on the tag's page nor by a scan:
  every name is typed.
- A device read by tag name reads one atomic value per tag. STRING variables, a whole structure
  and a whole array are not read; a member or an element is read by its name.
- The driver sends three FINS commands and no other: memory area read, memory area write and
  controller data read. It never changes the PLC's operating mode, its clock or its program.

## Good to know {#good-to-know}

- Over UDP the station sends each request from a port of its own and the PLC answers to that port,
  which is how Omron's Ethernet ports are set by default. An Ethernet unit set to the static address
  conversion answers to port 9600 of the station instead, where the driver does not listen: read
  such a PLC over TCP.
- A FINS network other than 0 is reached through the routing tables set in the PLCs; the station
  routes nothing itself.
- An NJ/NX controller is first asked on the CIP route `1,0`, and when that gets no answer on 18
  followed by the controller's own IP address, such as `18,192.168.250.1`; the route that answered
  is tried first the next time. There is no route field.
- Each FINS tag is a request of its own, and a device sends one at a time, so the time one round of
  reads takes grows with the number of its tags.
