콘텐츠로 이동
무료 평가 시작

데이터 모델과 주소

Modbus 서버는 값을 네 가지 테이블(table)에 나눠 보관합니다. 클라이언트는 테이블마다 정해진 기능 코드로 값을 읽고 씁니다. 이 페이지는 MODBUS Application Protocol Specification V1.1b3의 §4.2 데이터 인코딩, §4.3 데이터 모델, §4.4 주소 모델을 근거로 합니다.

테이블 단위 접근 읽기 기능 코드 쓰기 기능 코드 주로 담는 값
코일(coils) 1비트 읽기·쓰기 01 05, 15 출력 접점, 운전 지령
이산 입력(discrete inputs) 1비트 읽기 전용 02 없음 입력 접점, 센서 상태
입력 레지스터(input registers) 16비트 읽기 전용 04 없음 측정값
보유 레지스터(holding registers) 16비트 읽기·쓰기 03 06, 16, 22, 23 설정값, 지령값
  • 테이블은 서로 독립입니다. 보유 레지스터 0과 입력 레지스터 0은 다른 값입니다.
  • 명세는 테이블이 장비 메모리에서 겹쳐도 된다고 허용합니다. 어떤 장비는 같은 메모리를 코일과 레지스터로 함께 보여 줍니다. 실제 배치는 장비 매뉴얼을 확인합니다.
  • 클라이언트는 입력 테이블(이산 입력, 입력 레지스터)에 쓸 수 없습니다. 이 값은 장비가 스스로 바꿉니다.

명세 §4.4는 데이터 모델의 요소를 1부터 n까지 번호로 부르고, PDU에서는 0부터 65535까지의 주소(address)로 가리킨다고 정합니다. 즉 “1번 보유 레지스터”는 PDU 주소 0입니다.

장비 매뉴얼은 여기에 테이블 접두 숫자를 붙인 관례 표기를 자주 씁니다. 이 표기는 매뉴얼의 약속일 뿐이며, 접두 숫자는 PDU에 실리지 않습니다.

매뉴얼 표기 테이블 기능 코드 PDU 주소
00001 코일 01 0
00010 코일 01 9
10001 이산 입력 02 0
30001 입력 레지스터 04 0
40001 보유 레지스터 03 0
40108 보유 레지스터 03 107 (0x006B)
400001 (6자리) 보유 레지스터 03 0

변환 규칙은 다음과 같습니다.

  1. 접두 숫자로 테이블과 기능 코드를 고릅니다.
  2. 남은 번호에서 1을 뺍니다.
  3. 결과를 16비트 주소로 PDU에 넣습니다.

일부 장비 매뉴얼은 처음부터 0 기반 주소를 적습니다. 매뉴얼에 “address 0 = 40001”처럼 기준이 적혀 있는지 먼저 확인합니다. 주소를 한 칸 잘못 잡으면 오류 없이 옆 레지스터 값이 돌아오므로 알아차리기 어렵습니다. 문제 해결도 참고합니다.

명세 §4.2에 따라 주소, 수량, 레지스터 값은 모두 빅 엔디언(big-endian)으로 보냅니다. 상위 바이트가 먼저 나갑니다. 레지스터 값 0x1234는 12 34 순서로 전송됩니다.

비트 테이블은 8비트씩 묶어 한 바이트에 담습니다. 첫 주소의 비트가 첫 바이트의 최하위 비트(LSB)입니다. 다음 예는 코일 0~7에 0xA5를 쓰고 다시 읽습니다.

쓰기 요청 PDU 0F 0000 0008 01 A5
| | | | +-- 값 0xA5 = 1010 0101b
| | | +----- 바이트 수 1
| | +---------- 수량 8
| +--------------- 시작 주소 0
+------------------ 기능 코드 15 (Write Multiple Coils)
코일 주소 7 6 5 4 3 2 1 0
비트 값 1 0 1 0 0 1 0 1 → 코일 0, 2, 5, 7이 1

수량이 8의 배수가 아니면 마지막 바이트의 남는 상위 비트는 0으로 채웁니다.

Modbus 레지스터는 16비트 하나뿐입니다. 부호, 단위, 배율과 32비트 값의 배치는 명세가 정하지 않으며 장비마다 다릅니다.

  • 부호 있는 16비트 값: -5는 0xFFFB(65531)로 전송됩니다. 2의 보수로 해석할지는 장비 매뉴얼을 따릅니다.
  • 배율: 23.1 °C를 231처럼 10배 정수로 보내는 장비가 많습니다.
  • 32비트 정수와 부동소수점: 두 레지스터를 씁니다. 순서는 장비마다 다릅니다. IEEE 754 단정밀도 10.0(0x41200000)의 예는 다음과 같습니다.
배치 레지스터 n 레지스터 n+1 설명
ABCD (빅 엔디언) 0x4120 0x0000 상위 워드가 먼저입니다.
CDAB (워드 교환) 0x0000 0x4120 하위 워드가 먼저입니다.

PDComm은 레지스터를 16비트 정수로만 다룹니다. 32비트 값의 조립과 분해는 애플리케이션이 장비 매뉴얼에 맞게 합니다.

PDComm 엔드포인트(endpoint)는 서버로 동작할 때 자신의 데이터 모델을 가집니다.

  • 새 엔드포인트는 네 테이블에 각각 주소 0부터 1024개 항목을 0으로 준비합니다.
  • data_set 명령은 한 테이블의 일부를 바꿉니다. 입력 테이블도 바꿀 수 있습니다. 이는 장비 쪽 입력이 변한 상황을 흉내 내는 것이며, Modbus 쓰기 기능이 생기는 것은 아닙니다.
  • model_set 명령은 네 테이블의 시작 주소와 크기, 파일 레코드, FIFO 큐, 장치 식별 객체를 한 번에 바꿉니다. 모델 밖의 주소를 요청하면 서버가 예외 02(Illegal Data Address)로 응답합니다.
  • data_get 명령은 현재 모델 전체를 JSON으로 돌려줍니다.

명령 형식은 JSON 명령 레퍼런스에 있습니다. 직접 다뤄 보려면 튜토리얼: 주소와 프레임 관찰을 따라 합니다.