Modbus TCP

TCP/IP 위의 Modbus 레지스터와 코일이며, 형식 있는 주소 지정과 바이트 순서 조절과 한도가 정해진 네트워크 스캔을 갖추고 있습니다.

Markdown으로 보기

Modbus TCP 드라이버는 TCP/IP 위로 Modbus 레지스터와 코일을 읽고 씁니다. PLC, 계측기, 게이트웨이, 그리고 Modbus/TCP를 말하는 모든 서버가 상대입니다. 주소 지정은 완전히 형식이 있습니다. 레지스터 종류와 0부터 세는 레지스터 번호를 고르면 애플리케이션이 버스 요청을 조립합니다. 잘못 적을 자유 입력 주소가 없습니다.

장치

기본값
호스트 Modbus 서버나 게이트웨이의 DNS 이름, IPv4 주소, IPv6 주소. 비워 두면 localhost
포트 TCP 포트. 502(0으로 설정하면 502로 되돌아갑니다)
슬레이브 ID 요청마다 실려 가는 Modbus 슬레이브 id이며, 게이트웨이가 그 뒤에 있는 장치로 보낼 때 쓰는 값입니다. 0에서 255까지. 1
최소 트랜잭션 간격 (ms) 호환을 돕는 속도 맞춤입니다. 트랜잭션 하나가 끝난 뒤 다음이 시작될 때까지의 최소 침묵이며 0에서 1000까지입니다. 0은 인위적인 지연을 두지 않습니다. 0
읽기 주기 (ms) 스스로 값을 정하지 않은 태그의 기본 읽기 주기. 1000

패널 머리글에 나오는 기본 URI는 modbus+tcp://host:port/unitID이며, 간격을 정했으면 ?minimumTransactionIntervalMs=n이 붙습니다.

호스트와 포트를 함께 쓰는 장치들은 트랜잭션 관문도 함께 씁니다. 같은 엔드포인트로 가는 요청은 결코 겹치지 않으며, 그 엔드포인트에 있는 켜진 장치 가운데 가장 큰 최소 트랜잭션 간격이 그 모두의 속도를 정합니다. 다른 장치가 여기에 설정한 값보다 실제 적용되는 간격을 올릴 때는 패널이 그렇게 말합니다. 이 간격은 이 애플리케이션이 내보내는 통신만 다스립니다. 느린 서버나 게이트웨이를 위한 호환 수단이지 네트워크 고장을 고치는 수단이 아닙니다.

접속은 최대 5초를 기다리고, 응답은 최대 10초를 기다리며, 프로토콜 단계의 재시도는 없습니다. 배경의 재시도 고리가 다시 연결하는 일을 맡으므로, 꺼져 있는 장치는 품질이 나쁜 읽기 말고는 아무 비용도 들이지 않습니다.

태그 주소 지정

기본값
레지스터 종류 태그가 가리키는 Modbus 개체입니다. HoldingRegister, InputRegister, Coil, DiscreteInput 가운데 하나입니다. 형식과 접근에서 이끌어 냅니다. 부울 태그는 DiscreteInput(읽기 전용)이나 Coil(쓰기 가능)을, 그 밖의 모든 형식은 InputRegister(읽기 전용)나 HoldingRegister(쓰기 가능)를 받습니다.
레지스터 번호 (0부터) 프로토콜의 원래 주소입니다. 이것은 고전적인 4xxxx 표기가 아니라 버스 위의 0부터 세는 주소입니다. 홀딩 레지스터 "40001"은 레지스터 번호 0입니다. 레지스터는 16비트 수로 버스를 지나가므로, 이 칸은 0에서 65535까지를 받고 그보다 넓은 값은 입력하는 자리에서 거부합니다. 0
개수 (레지스터, 비우면 자동) 값이 차지하는 16비트 레지스터의 수입니다. 이 상자는 문자열 태그에만 그려집니다. 그 밖의 모든 형식은 너비가 고정되어 있어 정해 줄 것이 없기 때문입니다. 형식별로 부울 1, Int32와 Float 2, 문자열 4
최상위 바이트 먼저 각 16비트 레지스터에서 어느 바이트가 버스에 먼저 나가는지. 숫자 태그에만 있습니다. 켜짐(Modbus 규격이 요구하는 것)
최상위 워드 먼저 두 레지스터로 이루어진 값에서 어느 레지스터가 위쪽 절반을 담는지. 숫자 태그에만 있습니다. 켜짐

신호원 카드는 조립된 버스 주소(예를 들어 100?quantity=2)를 읽기 전용 미리 보기로 보여 주므로, 패널이 보여 주는 것이 요청이 담는 것과 정확히 같습니다.

값 형식과 개수

값 형식은 넷이 제시되고, 각각의 프로토콜 너비는 고정되어 있습니다.

데이터 형식 레지스터 버스 위의 모습
Boolean 1 레지스터 종류 위에서는 0이 아닌 레지스터가 모두 true로 읽히고, 쓰기는 1이나 0을 보냅니다. CoilDiscreteInput 위에서는 그 비트 자체입니다.
Int32 2 레지스터 두 개에 걸친 32비트 부호 있는 정수.
Float 2 레지스터 두 개에 걸친 IEEE 754 단정밀도.
String 1개 이상(기본 4) 레지스터마다 두 바이트씩 담는 UTF-8 바이트입니다. 읽기는 첫 NUL 바이트에서 멈추고, 쓰기는 선언한 개수(레지스터당 2바이트) 안에 들어가야 하며 0으로 채워집니다.

문자열 태그는 장치가 바이트를 담고 있는 순서 그대로 읽고 쓰며, 쓰기는 언제나 UTF-8로 보냅니다. 올바른 UTF-8이 아닌 바이트는 장치가 한 번도 초기화하지 않은 범위나 다른 인코딩으로 적힌 글자가 그렇게 보이는 것인데, 실패하는 대신 유니코드 대체 문자로 읽힙니다. 태그는 눈에 띄게 잘못된 것을 보여 주고, 그 장치의 다른 태그는 모두 계속 읽힙니다.

개수는 문자열 태그에만 묻습니다. 부울과 Int32와 Float의 너비는 고정되어 있으므로 그 지점에서는 태그 패널에도 태그 표에도 이 상자가 그려지지 않습니다. 이 값을 정해 주는 일은 문자열 태그의 크기를 잡기 위해 있습니다.

바이트와 워드 순서

두 순서 상자는 숫자 태그에 그려집니다. 서로 독립된 물음입니다. 레지스터 안에서 어느 바이트가 앞서는지, 그리고 한 쌍에서 어느 레지스터가 앞서는지입니다. Modbus는 글자에 대해서는 둘 다 정하지 않으므로 문자열 태그에는 이 상자가 제시되지 않습니다. 그 바이트는 장치가 담고 있는 순서 그대로 지나갑니다. 값 0x01020304에서 A를 최상위 바이트라고 하면 네 가지 배치는 이렇습니다.

최상위 바이트 먼저 최상위 워드 먼저 버스 위의 바이트
켜짐 켜짐 AB CD(규격의 기본값)
켜짐 꺼짐 CD AB(고전적인 워드 뒤바꿈)
꺼짐 켜짐 BA DC
꺼짐 꺼짐 DC BA

읽기와 쓰기는 같은 두 답을 같은 순서로 적용하므로, 쓰기는 읽기가 되가져왔을 바로 그 바이트를 그대로 놓습니다.

기능 코드

레지스터 종류 읽기 쓰기
HoldingRegister 3 (Read Holding Registers) 6 (레지스터 하나) 또는 16 (레지스터 여럿)
InputRegister 4 (Read Input Registers) 읽기 전용이며 쓰기는 거부됩니다
Coil 1 (Read Coils) 5 (Force Single Coil, 코일 하나)
DiscreteInput 2 (Read Discrete Inputs) 읽기 전용이며 쓰기는 거부됩니다

쓰기는 서버의 프로토콜 응답이 받아들였다고 확인했을 때에만 성공을 돌려줍니다. 캐시된 값도 그때에만 앞으로 나아갑니다.

장치 검색

스캔은 명시적이고 한도가 정해져 있습니다. 애플리케이션은 결코 로컬 서브넷을 추측하거나 훑지 않습니다. 범위 양식이 받는 것은 이렇습니다.

기본값
IPv4 호스트 또는 CIDR 주소 하나(192.168.1.10), 또는 /24보다 넓지 않은 서브넷(192.168.1.0/24)입니다. 네트워크 주소와 브로드캐스트 주소는 건너뜁니다. 필수
포트 탐색할 포트. 502
슬레이브 ID 값, 쉼표로 구분한 목록, 또는 오름차순 범위입니다. 1, 1,5,9, 1, 3, 8-16(0에서 255까지). 1
최소 트랜잭션 간격 (ms) 같은 호스트에서 끝난 탐색 사이의 속도 맞춤이며 0에서 1000까지입니다. 0

한 번의 스캔은 탐색 256회(호스트 × 슬레이브 ID)까지 보낼 수 있습니다. 그보다 큰 계획은 소켓을 열기 전에 거부됩니다. 보내는 요청은 Read Basic Device Identification(기능 43/14) 하나뿐입니다. 장치 검색은 결코 레지스터를 읽지 않고 레지스터 지도를 추측하지도 않습니다. 형식이 완전히 맞는 Modbus 예외 응답은 신원을 주장하지 않고도 그 슬레이브가 있다는 것을 증명합니다. TCP로 닿는다는 사실과 시간 초과와 깨진 프레임은 증명하지 못합니다. 최대 네 호스트를 나란히 스캔하고 호스트 안에서는 차례로 스캔하며, 접속과 탐색의 시간 초과는 750 ms입니다.

결과는 완전한 엔드포인트를 담고 있으며, 장치가 제조사와 제품 코드를 알려 주면 그것으로 지은 이름을 제안합니다. 후보의 태그는 0개입니다. 레지스터는 추가한 뒤에 설정합니다. 이미 설정된 슬레이브에는 그렇다는 표시가 붙고, 중복을 만드는 대신 열기를 내놓습니다.

알아 둘 만한 한계

  • 넓은 정수 형식(Int64, 부호 없는 너비들)과 Double은 제시되지 않습니다. 버스 코덱이 정확히 왕복하는 것은 위의 네 형식입니다.
  • 엔드포인트마다 한 번에 요청 하나만 나가 있습니다. 게이트웨이 하나 뒤에 있는 여러 장치는 그 직렬화를 설계대로 함께 씁니다.
  • 쓰기는 한 번에 코일 하나나 레지스터 한 묶음을 다룹니다. 코일 여러 개를 한 번에 쓰는 일은 없습니다.