# Omron

> Omron PLC에 연결합니다. CJ, CS, CP 컨트롤러는 FINS(UDP, TCP 또는 시리얼 회선의 Host Link)로 메모리 주소를, NJ, NX, NY 컨트롤러는 EtherNet/IP로 변수 이름을 가리켜 읽습니다. FINS 설정, 주소 형식, 데이터 형식, 읽기, 쓰기와 장치 검색.

**Omron** 드라이버는 Omron PLC와 그 두 가지 언어 중 하나로 이야기하며, 어느 쪽을 쓸지는 장치마다 고릅니다. CJ, CS, CP 컨트롤러와 CJ 메모리 모드로 설정한 NJ나 NX는 FINS로 메모리 주소를 가리켜 읽습니다. 주소는 Omron 프로그래밍 소프트웨어가 쓰는 그대로 `D100`, `W0.01`, `CIO100.05`처럼 적습니다. NJ, NX, NY 컨트롤러는 네트워크에 공개한 변수의 이름, 예를 들어 `Level`이나 `Motor.Speed`를 가리켜 EtherNet/IP로 읽습니다. 한 스테이션이 두 종류를 한 드라이버 아래에서 나란히 읽습니다. [Connector](connector)에서 Omron 드라이버 아래에 장치를 추가하고 그 **프로토콜**을 고르십시오. 패널은 그 프로토콜이 쓰는 칸만 보여 줍니다.

## 프로토콜 {#protocols}

| 프로토콜 | 컨트롤러 | 태그 주소를 가리키는 방법 | 포트 |
| --- | --- | --- | --- |
| **FINS** | CJ1, CJ2, CS1, CP1 등 Ethernet 포트나 유닛이 있는 CJ, CS, CP 컨트롤러, 그리고 CJ 메모리 모드의 NJ나 NX | **메모리 주소**, 예: `D100`, `W0.01` | 기본값 9600 |
| **NJ/NX 태그(이름으로 지정)** | NJ, NX, NY 컨트롤러, 예: NJ501, NJ301, NJ101, NX1P2, NX102, NX502, NX701, NY5 | **변수 이름**, 예: `Level`, `Motor.Speed` | 없음. EtherNet/IP는 표준 포트 44818에서 응답합니다 |

기본값은 FINS이며 새 장치는 FINS로 시작합니다. 프로토콜은 장치의 설정이므로, CJ2와 NX1P2가 같은 드라이버 아래에 놓이고 저마다 자기 언어로 읽힙니다. 프로토콜을 바꿔도 FINS 설정은 남겨 둔 그대로 보존되어 FINS로 돌아올 때 쓰이고, 장치의 모든 태그는 그때부터 새 프로토콜로 주소를 읽습니다. 태그의 **데이터 형식**은 그 주소가 새 프로토콜에서 담을 수 있는 형식으로 맞춰지고, 새 프로토콜이 읽을 수 없는 주소는 고칠 때까지 태그 페이지에 표시가 남습니다.

## 연결 {#connection}

| 칸 | 의미 | 기본값 |
| --- | --- | --- |
| **호스트** | PLC의 Ethernet 포트나 유닛의 IP 주소 또는 호스트 이름. | 비어 있음 |
| **프로토콜** | **FINS** 또는 **NJ/NX 태그(이름으로 지정)**. 그 아래 줄이 지금 프로토콜이 무엇을 읽는지 알려 줍니다. "CJ, CS, CP 컨트롤러의 메모리 영역과 CJ 메모리 모드의 NJ/NX 메모리 영역입니다." 또는 "NJ, NX, NY 컨트롤러가 네트워크에 공개하는 변수를 이름으로 EtherNet/IP를 통해 읽습니다." | FINS |
| **포트** | FINS에만 있습니다. PLC가 FINS에 응답하는 포트로, UDP와 TCP에서 같고 1에서 65535까지입니다. 칸이 비어 있으면 9600이 회색으로 보이고 장치는 그 포트로 호출됩니다. 이름으로 읽는 장치에는 포트 칸이 없습니다. | 9600 |
| **읽기 주기 (ms)** | 자기 주기를 두지 않은 태그를 읽는 장치 전체의 주기입니다. | 1,000 |

장치 머리글은 조립된 endpoint를 보여 줍니다. FINS 장치는 모든 설정을 거기에 적으며, 노드 0은 자동을 뜻합니다. 예를 들어 `omron://192.168.250.1:9600?protocol=fins&transport=udp&network=0&node=0&unit=0&source=0&timeoutMs=2000`입니다. 이름으로 읽는 장치는 호스트와 프로토콜만 적습니다. `omron://192.168.250.1?protocol=njnx`입니다. 태그마다 자기 **읽기 주기 (ms)**를 둘 수 있으며, 태그의 값이 0이면 장치의 주기를 따릅니다.

## 컨트롤러 준비 {#prepare-the-controller}

이름으로 읽는 NJ, NX, NY 컨트롤러는 네트워크에 공개한 전역 변수만 제공합니다. 공개는 변수마다의 속성이며, Sysmac Studio에서 설정해 컨트롤러로 전송합니다. FINS로 읽는 컨트롤러에는 이런 설정이 필요 없습니다.

| 설정 | Sysmac Studio에서의 위치 | 설정이 없으면 |
| --- | --- | --- |
| 스테이션이 읽거나 쓰는 모든 전역 변수에서 **Network Publish**를 **Publish Only**로(태그 데이터 링크에서도 쓰는 변수라면 Input이나 Output) | **Programming > Data > Global Variables**에서 그 변수의 **Network Publish** 열. 프로젝트를 컨트롤러로 전송합니다(**Controller > Synchronize**). | 컨트롤러는 존재하지 않는 이름과 똑같이, 그 이름의 변수를 제공하지 않는다고 답합니다. 태그는 품질이 나쁜 것으로 읽히고, 장치의 다른 태그는 계속 읽힙니다. |

프로그램의 변수(로컬 변수)는 공개할 수 없습니다. 전역 변수로 선언하거나, 프로그램 안에서 전역 변수로 복사하십시오.

태그 이름의 변수를 제공하지 않는다고 컨트롤러가 답하면, 장치 페이지가 그 변수와 그것을 읽는 태그를 밝히고, 두 가지 원인(존재하지 않는 이름이거나 공개되지 않은 변수)과 이 단계를 알림으로 보여 줍니다. 알림은 변수가 읽히면 저절로 사라지며, 태그 자신의 페이지에도 같은 알림이 나옵니다. 진단 로그와 에이전트도 같은 단계를 읽습니다.

## FINS 카드 {#the-fins-card}

FINS로 읽는 장치에는 연결 카드 아래에 **FINS** 카드가 붙습니다. 요청을 무엇에 실어 보낼지, 누구에게 보낼지, 요청마다 응답을 얼마나 기다릴지를 정합니다. 이름으로 읽는 장치에는 이 카드가 없습니다.

| 칸 | 의미 | 기본값 |
| --- | --- | --- |
| **전송 프로토콜** | **UDP**: "요청마다 데이터그램 하나를 보내고, 보낸 포트로 응답을 받습니다. Omron Ethernet 포트의 기본값입니다." **TCP**: "연결 하나를 열고, 그 안에서 PLC가 이 스테이션에 FINS 노드를 할당합니다." | UDP |
| **네트워크** | "PLC의 FINS 네트워크입니다. 이 스테이션의 네트워크면 0, PLC의 라우팅 테이블을 거치면 1부터 127까지입니다." | 0 |
| **PLC 노드** | PLC의 FINS 노드로 1부터 254까지입니다. 비워 두면 칸에 "자동"이 보이며, UDP에서는 PLC IP 주소의 마지막 숫자(`192.168.250.1`의 PLC는 노드 1), TCP에서는 연결이 열릴 때 PLC가 알려 주는 노드입니다. | 자동 |
| **유닛** | "PLC 안에서 응답하는 유닛입니다. CPU 유닛은 0입니다." 255까지입니다. | 0 |
| **스테이션 노드** | UDP에만 있습니다. 이 스테이션의 FINS 노드로 1부터 254까지입니다. 비워 두면 칸에 "자동"이 보이며, PLC에 닿는 네트워크에서 이 스테이션 IP 주소의 마지막 숫자입니다. TCP에서는 PLC가 연결 안에서 노드를 할당하므로 이 칸을 그리지 않습니다. | 자동 |
| **응답 제한 시간 (ms)** | "FINS 요청이 응답을 기다리는 시간입니다." 100부터 60,000까지입니다. | 2,000 |

범위를 벗어난 숫자는 칸 아래에서 거부됩니다. 예를 들어 "0에서 127 사이의 숫자를 입력하십시오."가 나오고 칸은 지금 값으로 돌아갑니다. 전송을 TCP로 바꿔도 UDP용으로 넣은 스테이션 노드는 남지만, 장치는 그것을 쓰지 않습니다.

## 시리얼 회선의 Host Link {#host-link-on-a-serial-line}

시리얼 포트만 있는 CP1E, CP1L, CP1H, CJ, CS 컨트롤러(RS-232C, 또는 옵션 보드나 변환기를 거친 RS-485와 RS-422A)는 Omron 드라이버의 시리얼 회선을 통해 Host Link 위의 FINS로 읽습니다. COM 포트 하나를 PLC 최대 32대가 함께 쓰고, 각 PLC는 자기 유닛 번호로 응답합니다. 드라이버 페이지의 시리얼 회선 표에서 **회선 추가**로 회선을 추가하고 **시리얼 포트**, **보 레이트**, **시리얼 형식**를 PLC 시리얼 포트의 설정에 맞춘 다음(회선 페이지의 나머지는 [시리얼 회선](connector-lines)에 있습니다), 회선을 켜고, 회선 페이지의 **장치 추가**로 PLC를 한 대씩 추가합니다.

| 설정 | 위치 | 값 |
| --- | --- | --- |
| 포트 모드 | PLC의 PLC Setup에서, 회선을 연결한 시리얼 포트 | Host Link |
| 보 레이트와 형식 | 회선 | PLC 포트의 설정대로. Host Link 포트는 출고 시 9600보와 `7E2`입니다 |
| **유닛 ID** | 장치의 연결 카드, **시리얼 회선 · 고정** 옆 | PLC Setup에서 정한 PLC의 Host Link 유닛 번호로, 0부터 31까지입니다. 새 장치는 회선에서 비어 있는 첫 번호를 받고, 회선의 다른 PLC가 쓰는 번호는 거부됩니다 |
| **응답 제한 시간 (ms)** | 장치의 FINS 카드 | 100부터 60,000까지. 기본값 2,000 |

회선에 있는 장치는 계속 FINS로 읽습니다. **프로토콜**, **호스트**, **포트** 칸이 없고, FINS 카드에는 "이 시리얼 회선에서 Host Link로 FINS를 보냅니다. 대상은 유닛 번호(PLC Setup에서 시리얼 포트에 설정한 값)가 위의 유닛 ID와 같은 PLC입니다."와 **응답 제한 시간 (ms)**만 나옵니다. 요청이 버스가 가리키는 PLC의 CPU 유닛으로 가고 네트워크 항목은 쓰이지 않기 때문입니다. 네트워크로 옮겨 가는 일은 없고, 네트워크 장치가 회선으로 옮겨 오는 일도 없습니다. 태그는 네트워크에서와 같이 주소를 씁니다(`D100`, `W0.01`). endpoint는 회선과 유닛을 가리킵니다. 예: `omron://serial/<line id>/COM5/9600/7E2?protocol=fins&transport=hostlink&hostLinkUnit=0&timeoutMs=2000`.

| 시리얼 회선에서 | 일어나는 일 |
| --- | --- |
| 한 회선에 PLC 여러 대 | 회선 전체에서 요청과 그 응답을 한 번에 하나씩 처리합니다. 다른 유닛의 응답이나 잡음은 건너뜁니다 |
| 제한 시간 안에 응답하지 않는 PLC | 그 장치는 다시 연결합니다. 회선의 다른 PLC는 계속 읽습니다 |
| PLC가 프레임을 손상된 것으로 보고 `13 (FCS error)` 같은 Host Link 종료 코드로 응답 | 그 장치는 다시 연결합니다 |
| 어댑터를 뽑은 경우처럼 포트가 고장 남 | 회선의 모든 장치가 다시 연결합니다. 포트는 1초 쉰 뒤 다시 열리고, 쉬는 시간은 최대 1분까지 두 배씩 늘어납니다 |
| 문자열 태그 | 최대 534자로, Host Link 프레임 하나에 담기는 만큼입니다 |

스캔은 시리얼 회선을 찾지 않습니다. PLC는 한 대씩 유닛 번호로 추가하십시오.

## 주소 지정 {#addressing}

태그의 주소는 태그 신호원 카드의 한 칸으로 적으며, 칸 이름은 장치의 프로토콜을 따릅니다. FINS에서는 **메모리 주소**, 이름으로 읽는 장치에서는 **변수 이름**이고, 그 아래에 프로토콜의 힌트가 나옵니다. 드라이버가 읽을 수 없는 주소는 입력하는 그 자리에서 태그 페이지가 이유와 함께 거부합니다. 신호원 카드의 읽기 전용 줄 **신호원 주소 (버스)**가 드라이버가 받는 주소를 보여 줍니다.

### 메모리 주소(FINS) {#memory-addresses-fins}

메모리 주소는 영역의 문자, 10진수 워드 번호, 그리고 비트 하나라면 점과 비트 번호(00부터 15까지)로 씁니다. 문자는 대소문자를 구별하지 않으며, 예전 표기도 읽습니다.

| 영역 | 예 | 워드 | 다른 표기 |
| --- | --- | --- | --- |
| CIO | `CIO100`, `CIO100.05`, `100.05` | 0부터 6143까지 | 숫자만 써도 CIO 주소입니다 |
| 작업(W) | `W0`, `W0.01` | 0부터 511까지 | `WR` |
| 유지(H) | `H10`, `H10.00` | 0부터 1535까지 | `HR` |
| 보조(A) | `A100`, `A100.03` | 0부터 1471까지 | `AR` |
| 데이터 메모리(D) | `D100`, `D100.15` | 0부터 32767까지 | `DM` |
| 확장 데이터 메모리(E) | `E0_100`, `EA_0`, `E18_0` | 0부터 32767까지 | E와 밑줄 사이에 16진수 뱅크 번호(0부터 18까지) |

각 영역의 한계는 CJ, CS, CP 컨트롤러 가운데 가장 큰 것을 따릅니다(CJ2에는 유지 워드가 1,536개 있고 확장 데이터 메모리 뱅크가 18까지 있습니다). 작은 컨트롤러에 없는 워드나 뱅크는 그 PLC가 직접 답하는 일이며, 태그를 처음 읽을 때 오류가 됩니다([읽기](#reading) 참조). 태그 페이지가 입력하는 자리에서 거부하는 것은 이렇습니다.

| 입력한 것 | 태그 페이지가 보여 주는 문장 |
| --- | --- |
| 영역, 워드, 비트의 형태가 아닌 것, 예: `X100`, `D100.` | "FINS 메모리 주소는 영역과 워드, 비트라면 점과 비트 번호를 붙여 씁니다(예: D100, W0.01, CIO100.05, H10, A100, E0_100)." |
| 영역의 끝을 넘은 워드, 예: `D40000`, `W512` | "그 워드는 어느 CJ, CS, CP 컨트롤러에서도 해당 영역의 마지막 워드보다 뒤에 있습니다." |
| 15를 넘은 비트, 예: `W0.16` | "워드의 비트 번호는 00부터 15까지입니다." |
| 18을 넘은 뱅크, 예: `E19_0` | "확장 메모리 뱅크 번호는 16진수로 0부터 18까지입니다." |

버스 주소는 비트를 두 자리로 맞춘 한 가지 표기의 주소입니다. `100.5`는 `CIO100.05`로, `DM100`은 `D100`으로 보내집니다. 문자열 태그는 `?` 뒤에 차지하는 문자 수를 붙이므로, D200에 있는 16자 문자열은 `D200?16`으로 보내집니다.

### 변수 이름(NJ/NX) {#variable-names-njnx}

NJ, NX, NY 컨트롤러는 네트워크에 공개한 전역 변수의 이름으로 읽습니다. Sysmac Studio로 말하면 Network Publish 속성이 Publish Only, Input, Output 중 하나인 변수입니다([컨트롤러 준비](#prepare-the-controller) 참고). 컨트롤러가 공개하지 않은 변수는 이름으로 읽을 수 없습니다. 이름은 ASCII 영문자, 숫자, 밑줄로 쓰고 숫자로 시작하지 않으며, 구조체 멤버 앞에는 점을 찍고 인덱스는 대괄호로 묶습니다. `Level`, `Motor.Speed`, `Temps[3]`, `Grid[1,2]`처럼 씁니다. 다른 형태는 태그 페이지가 거부합니다. "변수 이름은 영문자, 숫자, 밑줄로 쓰고 숫자로 시작하지 않습니다. 멤버 앞에는 점을 찍고 인덱스는 대괄호로 묶습니다(예: Level, Motor.Speed, Temps[3])." Sysmac Studio가 허용하는 다른 문자로 쓴 이름도 똑같이 거부됩니다. EtherNet/IP 요청이 그것을 실어 나를 수 없기 때문입니다.

컨트롤러는 이 드라이버가 읽지 않는 방식으로 변수 목록을 내놓으므로, 이름으로 읽는 장치의 태그는 모두 손으로 입력합니다. 컨트롤러가 그 이름을 공개하는지는 태그를 처음 읽을 때 컨트롤러가 직접 답합니다. 오프셋 칸은 없습니다. 멤버나 요소는 그 자체의 이름으로 가리키며, BOOL 배열의 요소도 `Flags[5]`처럼 자기 이름으로 읽습니다. 버스 주소는 이름 뒤에 `?0`을 붙인 것이며, 예를 들어 `Motor.Speed?0`입니다.

## 데이터 형식 {#data-types}

FINS에서는 고를 수 있는 **데이터 형식**이 주소에 따라 정해집니다.

| 주소가 가리키는 것 | 데이터 형식 | 읽는 것 |
| --- | --- | --- |
| 비트, 예: `W0.01` | Boolean | 그 비트만. |
| 워드, 예: `D100` | Int16 또는 UInt16 | 그 워드. |
| 워드와 그다음 워드 | Int32, UInt32 또는 Float | 워드 두 개. 주소에 하위 워드를, 그다음에 상위 워드를 둡니다. Omron 자체 명령이 더블 워드를 두는 순서입니다. 영역의 마지막 워드는 쌍을 시작할 수 없으므로 Int16, UInt16, String만 고를 수 있습니다. |
| 워드와 그 뒤 워드들을 문자열로 | String | 태그가 선언하는 **길이 (문자 수, 비우면 16)**만큼, 1자부터 1998자까지, 워드 하나에 두 글자씩, 앞 글자를 상위 바이트에 둡니다. 문자열은 첫 NUL에서 끝납니다. 시리얼 회선에서는 1자부터 534자까지입니다. |

태그의 형식을 담을 수 없는 주소를 입력하면, 형식은 그 주소가 가장 자연스럽게 읽는 형식으로 바뀝니다. 비트는 Boolean, 워드는 Int16입니다. 주소가 담을 수 없는 형식은 담을 수 있는 형식을 들어 거부됩니다. 예를 들어 "주소 D100은(는) 다음 데이터 형식 중 하나로 읽습니다: Int16, UInt16, Int32, UInt32, Float, String."입니다. 바이트 순서나 워드 순서를 고르는 옵션은 없습니다. FINS는 모든 워드에서 상위 바이트를 먼저 두며, 드라이버가 그것을 처리합니다.

이름으로 읽는 장치는 컨트롤러의 원자 형식을 모두 고를 수 있습니다.

| 데이터 형식 | Sysmac Studio의 변수 형식 |
| --- | --- |
| Boolean | BOOL |
| SByte | SINT |
| Byte | USINT |
| Int16 | INT |
| UInt16 | UINT |
| Int32 | DINT |
| UInt32 | UDINT |
| Int64 | LINT |
| UInt64 | ULINT |
| Float | REAL |
| Double | LREAL |

WORD 변수는 UInt16으로, DWORD 변수는 UInt32로 읽습니다. STRING 변수는 읽지 않으며 String은 고를 수 없습니다. 목록에 없는 형식은 목록을 들어 거부됩니다. "NJ/NX 컨트롤러의 변수는 다음 데이터 형식 중 하나로 읽습니다: Boolean, SByte, Byte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Float, Double."

## 읽기 {#reading}

FINS에서 장치는 PLC와 대화 하나를 유지하며 요청을 하나씩 보냅니다. 태그 하나가 그 워드들에 대한 메모리 영역 읽기 한 번입니다. 응답으로는 그 요청 자신의 번호가 붙은 답만 받으므로, 늦게 온 답을 다음 요청의 답으로 읽는 일은 없습니다. 태그를 읽기 전에 PLC는 컨트롤러 데이터 읽기에, 어떤 종료 코드로든 응답해야 합니다. PLC가 알려 주는 모델은 진단 로그에 적힙니다. 그다음에는 PLC의 답이 각 읽기의 결과를 정합니다.

| PLC의 답 | 읽기 |
| --- | --- |
| 정상 완료 | 값. |
| 그 점에 관한 종료 코드, 예: PLC에 없는 주소 | 그 태그는 값 없이 남고, 오류가 종료 코드와 Omron 매뉴얼에서의 뜻을 알려 줍니다. 예를 들어 `end code 0x1103 (address range error)`입니다. 장치의 다른 태그는 계속 읽습니다. |
| PLC까지 가는 경로에 관한 종료 코드(0x01xx, 0x02xx, 0x03xx, 0x05xx), 도중의 중계 노드에서 난 시간 초과, 또는 **응답 제한 시간 (ms)** 안에 아무 답도 없는 것 | 장치가 다시 연결하며, PLC가 다시 응답할 때까지 태그의 읽기는 실패합니다. 무엇을 보여 줄지는 [장치가 응답하지 않았을 때](connector-value-pipeline#the-device-did-not-answer)에 대한 태그별 정책이 정합니다. |

이름으로 읽는 장치는 어떤 프로그램도 선언하지 않는 변수를 컨트롤러에 물어 확인합니다. 그런 이름은 없다는 컨트롤러의 답이 곧 컨트롤러에서 온 답이기 때문입니다. 이 장치의 요청은 [Rockwell EtherNet/IP](driver-rockwell) 드라이버와 같은 EtherNet/IP 코드를 거치며, 10초 뒤에 시간이 초과됩니다.

## 쓰기 {#writes}

**접근**이 읽기와 쓰기이거나 쓰기 전용인 태그는 쓸 수 있습니다. 새 태그는 읽기 전용으로 시작합니다. 쓰기는 장치의 대기열에서 읽기와 함께 차례를 기다리며, 요청받은 값만 보내고 그 밖의 것은 보내지 않습니다.

| 태그가 읽는 것 | 쓰기가 보내는 것 |
| --- | --- |
| FINS 비트(`W0.01`) | 그 비트만. PLC는 그 비트를 그 자리에서 바꾸고 워드의 다른 비트는 그대로 둡니다. |
| FINS 워드 또는 더블 워드 | 값 전체를, 주소에, 그리고 워드가 둘이면 다음 워드에. |
| FINS 문자열 | 선언한 길이 전체. 앞에 문자열을, 뒤에 NUL을 두므로 예전에 쓴 더 긴 문자열이 뒤에 남아 다시 읽히는 일이 없습니다. 길이에 들어가지 않는 문자열은 잘라 내지 않고 거부합니다. |
| NJ/NX 변수 | 값을, 그 이름의 변수로. BOOL 배열의 요소는 그 BOOL 하나만 씁니다. |

| FINS 쓰기에 대한 PLC의 답 | 쓰기 |
| --- | --- |
| 정상 완료 | 전달됨. |
| 쓰기를 거절하는 종료 코드 | 거부됨. 이유가 종료 코드와 그 뜻을 알려 줍니다. 예를 들어 `end code 0x2101 (read-only)`입니다. |
| **응답 제한 시간 (ms)** 안에 아무 답도 없음, 또는 도중의 중계 노드에서 난 시간 초과(0x0205) | 응답 없음. |

태그의 형식이 담을 수 없는 값의 FINS 쓰기는 아무것도 보내기 전에 거부됩니다.

## 장치 검색 {#discovery}

Omron 드라이버 페이지에는 **스캔 범위** 카드가 있고, 선택 입력 칸이 하나 있습니다. "FINS로 탐색할 PLC 주소, 예: 192.168.250.1(비우면 브로드캐스트로 NJ/NX만 찾습니다)"입니다. 장치 검색은 그다음 최대 두 가지를 차례로 묻습니다.

| 질문 | 언제 | 내놓는 것 |
| --- | --- | --- |
| FINS와 UDP로 하는 컨트롤러 데이터 읽기. 노드는 모두 자동이며, 칸에 적은 PLC로 보냅니다. 칸에는 IP 주소나 이름을 쓰고, PLC가 9600이 아닌 포트에서 FINS에 응답하면 `:port`를 붙입니다. 진행 줄은 "192.168.250.1에 FINS로 식별 정보를 요청하는 중…"을 보여 줍니다. | 칸에 주소가 있을 때만. | 그 PLC를, 응답한 모델 이름을 붙인 FINS 장치로 `omron://<host>:<port>?protocol=fins&transport=udp&network=0&node=0&unit=0&source=0&timeoutMs=2000`에 내놓습니다. 아무 응답도 없는 PLC는 아무것도 내놓지 않습니다. |
| EtherNet/IP 식별 요청. 이 컴퓨터가 연결된 모든 네트워크에 브로드캐스트합니다. 진행 줄이 그 네트워크를 알려 줍니다. "192.168.0.255에서 Omron NJ/NX 컨트롤러를 찾는 중…" | 매번. 새 응답 없이 5초가 지날 때까지 듣습니다. | 응답한 NJ, NX, NY 컨트롤러를 저마다 이름으로 읽는 장치로, 제품 이름(예: NX1P2)을 붙여 내놓습니다. 제품 이름이 `NX-`로 시작하는 NX I/O 커플러는 변수를 갖지 않으므로 건너뛰며, 다른 Omron 제품도 마찬가지입니다. |

어느 질문도 태그는 찾지 않습니다. FINS PLC는 주소 목록을 공개하지 않고, NJ/NX는 드라이버가 읽지 않는 방식으로 변수 목록을 내놓으므로, 후보마다 "보고된 태그가 없습니다. 장치를 추가한 다음 편집기에서 태그를 설정하십시오."가 보입니다. 칸에 든 것이 호스트가 아니면 그 아래에서 거부되고 장치 검색은 회색이 됩니다. "Omron 스캔은 여기에 쓴 PLC에 FINS로 식별 정보를 요청합니다. IP 주소나 이름을 쓰고, 필요하면 포트를 붙입니다(예: 192.168.250.1 또는 192.168.250.1:9600). 브로드캐스트로 NJ/NX 컨트롤러만 찾으려면 비워 두십시오." 이 컴퓨터가 연결되지 않은 네트워크의 컨트롤러는 브로드캐스트에 응답하지 않으니 손으로 추가하십시오. Rockwell EtherNet/IP의 스캔도 같은 브로드캐스트를 듣지만 Omron 컨트롤러는 모두 이 드라이버에 맡깁니다. 스캔의 나머지 동작은 [장치 검색](connector-discovery)에 있습니다.

## 에이전트 도구 {#agent-tools}

`driver_capabilities`는 이 드라이버를 `omron` 아래에 설명합니다. 두 프로토콜 각각이 받는 장치 칸, 주소 형식, 데이터 형식과 FINS 전송 방식과 범위, 쓰기, 장치 검색입니다. `device_upsert driver=Omron`은 `omronProtocol`(`Fins` 또는 `NjNx`)을 받고, FINS에서는 `finsTransport`(`Udp` 또는 `Tcp`), `finsNetwork`, `finsNode`(0이면 자동), `finsUnit`, `finsSourceNode`(UDP에만, 0이면 자동), `finsResponseTimeoutMs`도 받습니다. 이름으로 읽는 장치는 포트도 FINS 칸도 받지 않습니다. `tag_upsert`는 메모리 주소나 변수 이름을 `address`로, 형식을 `opcUaType`으로(생략하면 비트는 Boolean, 워드는 Int16), FINS 문자열의 길이를 `wireQuantity`로 받습니다. `device_discover driver=Omron`이 스캔을 돌리며, FINS로 물을 대상은 `target`으로 줍니다. UDP로 읽는 CJ2와 이름으로 읽는 NX1P2의 예입니다.

```
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
```

시리얼 회선의 PLC는 이 드라이버의 회선에 매달립니다. `serial_line_upsert driver=Omron`이 회선을 만들고, `device_upsert driver=Omron serialLineId=<id>`가 PLC를 Host Link로 추가합니다(회선이 `finsTransport=HostLink`를 정합니다). `unitId`에는 유닛 번호 0부터 31까지를 넘기고(생략하면 비어 있는 첫 번호), `finsResponseTimeoutMs`도 넘길 수 있습니다. 네트워크 항목은 거부됩니다. COM5의 유닛 0에 있는 CP1L 예:

```
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
```

다른 도구는 [에이전트 도구](agent-tools)에 있습니다.

## 알아 둘 한계 {#limits-worth-knowing}

- 예전 C 모드 Host Link 명령만 쓰는 컨트롤러(CPM1, CPM2, CQM1, C200HS 등)는 [시리얼 회선](#host-link-on-a-serial-line)에서도, 변환기를 거쳐서도 읽지 못합니다. 드라이버는 FINS 명령만 보냅니다.
- 타이머와 카운터는 FINS에서 고를 수 없습니다. 현재값은 PLC 설정에 따라 BCD나 이진으로 보관되며, FINS 응답에는 어느 쪽인지 나와 있지 않기 때문입니다. 그런 값은 프로그램이 복사해 두는 워드를 통해 읽으십시오.
- NJ/NX 컨트롤러의 변수는 태그 페이지에서도 스캔에서도 목록으로 나오지 않습니다. 이름은 모두 입력합니다.
- 이름으로 읽는 장치는 태그 하나에 원자 값 하나를 읽습니다. STRING 변수, 구조체 전체, 배열 전체는 읽지 않으며, 멤버나 요소는 이름으로 읽습니다.
- 드라이버가 보내는 FINS 명령은 메모리 영역 읽기, 메모리 영역 쓰기, 컨트롤러 데이터 읽기 세 가지뿐입니다. PLC의 운전 모드, 시계, 프로그램을 바꾸는 일은 없습니다.

## 알아 두면 좋은 것 {#good-to-know}

- UDP에서 스테이션은 요청마다 자기 포트에서 보내고 PLC는 그 포트로 응답합니다. Omron Ethernet 포트가 출하될 때의 설정입니다. 정적 주소 변환으로 설정한 Ethernet 유닛은 대신 스테이션의 포트 9600으로 응답하는데, 드라이버는 거기서 듣지 않습니다. 그런 PLC는 TCP로 읽으십시오.
- 0이 아닌 FINS 네트워크에는 PLC에 설정한 라우팅 테이블을 거쳐 닿습니다. 스테이션 자신은 아무것도 중계하지 않습니다.
- NJ/NX 컨트롤러에는 먼저 CIP 경로 `1,0`으로 묻고, 답이 없으면 18 뒤에 컨트롤러 자신의 IP 주소를 붙인 경로, 예를 들어 `18,192.168.250.1`로 묻습니다. 응답한 경로는 다음번에 먼저 시도합니다. 경로 칸은 없습니다.
- FINS 태그는 하나하나가 독립된 요청이며 장치는 그것을 하나씩 보냅니다. 그래서 한 바퀴 읽기에 걸리는 시간은 태그 수에 따라 늘어납니다.
