PortDock

Modbus 함수 코드 정리 — 01~06·0F·10·17 언제 무엇을 쓰나

코일·입력 접점·레지스터를 읽고 쓰는 함수 9개를 표 하나로. 한 번에 보낼 수 있는 개수, 응답 모양, 06 과 10 중 고르는 법, 예외 01 이 날 때 볼 것.

Modbus 요청에서 국번(RTU) 또는 MBAP 머리(TCP) 바로 뒤의 한 바이트가 함수 코드입니다. 함수 코드가 «어느 표를 읽을지·쓸지» 를 정하고, 주소는 그 표 안의 0 기준 번호입니다. 공개 함수 코드 가운데 레지스터·코일을 다루는 것은 아래 9개입니다. 한도는 Modbus Application Protocol Specification V1.1b3 의 값입니다.

코드이름표한 번에 최대
01코일 읽기코일(0xxxx)2000개
02입력 접점 읽기입력 접점(1xxxx)2000개
03보유 레지스터 읽기보유 레지스터(4xxxx)125개
04입력 레지스터 읽기입력 레지스터(3xxxx)125개
05코일 하나 쓰기코일1개
06레지스터 하나 쓰기보유 레지스터1개
0F (15)코일 여러 개 쓰기코일1968개
10 (16)레지스터 여러 개 쓰기보유 레지스터123개
17 (23)레지스터 읽기·쓰기 한 번에보유 레지스터읽기 125개 · 쓰기 121개

매뉴얼은 함수 코드를 16진(0F·10·17)으로도 10진(15·16·23)으로도 적습니다. «FC16» 과 «FC10» 은 같은 함수입니다. 표의 한도는 규격의 최대값이고 장비는 더 적게 받을 수 있습니다 — 넘기면 예외 03(잘못된 값)이 옵니다.

읽기: 01·02 는 비트, 03·04 는 16비트 값

01·02 응답은 비트를 한 바이트에 8개씩 담고, 첫 바이트의 가장 낮은 비트가 요청한 첫 주소입니다. 코일 10개(주소 0~9)를 읽으면 데이터 2바이트가 옵니다.

요청  01 01 00 00 00 0A BC 0D
응답  01 01 02 05 01 7B 6C

첫 데이터 바이트 05 는 2진수 0000 0101 이라 코일 0 과 2 가 켜져 있고, 둘째 바이트 01 은 코일 8 이 켜져 있다는 뜻입니다. 마지막 바이트의 남는 비트는 0 으로 채웁니다.

03 과 04 는 요청·응답 모양이 같고 읽는 표만 다릅니다. 어느 값을 어느 표에 두는지는 장비가 정합니다 — 루텍 Accura 3300E 는 모든 값을 보유 레지스터(03)에 두고, LS ELECTRIC GIMAC1000 은 측정값을 입력 레지스터(04)에 둡니다. 매뉴얼의 함수 코드 칸을 따르세요. 03 으로 읽어 예외 02 가 나면 04 로도 읽어 봅니다.

쓰기: 하나씩(05·06)과 여러 개(0F·10)

05 코일 0 켜기             01 05 00 00 FF 00 8C 3A
06 레지스터 1 에 100       01 06 00 01 00 64 D9 E1
10 레지스터 0~1 에 10, 258  01 10 00 00 00 02 04 00 0A 01 02 53 FC

17: 쓰고 나서 읽기를 한 번에

17(23)은 한 요청으로 보유 레지스터를 쓰고 읽습니다. 규격상 쓰기를 먼저 한 뒤 읽습니다. 왕복이 한 번으로 줄지만 지원 여부가 장비마다 다르니 매뉴얼의 지원 함수 표를 먼저 봅니다. 아래는 주소 16 에 255 를 쓰고 주소 0 부터 2개를 읽는 예입니다.

요청  01 17 00 00 00 02 00 10 00 01 02 00 FF 56 6B
응답  01 17 04 00 64 00 C8 B9 6E

예외 01 이 오면

예외 응답은 함수 코드에 0x80 을 더해 옵니다(03 → 83, 06 → 86, 10 → 90). 예외 01(지원하지 않는 함수)은 장비에 그 함수가 없거나 지금 상태에서 받을 수 없다는 뜻이니 지원 함수 표를 보고 다른 함수로 바꿉니다. 02 는 주소, 03 은 개수·값 문제입니다.

01 86 02 C3 A1   ← 06 요청에 예외 02(없는 주소)

그 밖의 함수

0x07·0x08·0x0B·0x0C·0x11 은 시리얼 회선 전용 진단 함수, 0x14·0x15 는 파일 레코드, 0x16 은 마스크 쓰기, 0x18 은 FIFO 읽기, 0x2B 는 장치 식별 등에 쓰입니다. 레지스터·코일 값을 주고받는 데는 위 9개로 충분합니다.

PortDock 에서는

작성 2026-10-22