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
- 05 의 값은 FF 00(켬)과 00 00(끔) 둘뿐입니다. 00 01 같은 값은 규격상 잘못된 값입니다.
- 05·06 이 성공하면 장비는 요청을 그대로 돌려줍니다(에코). 0F·10 은 시작 주소와 개수만 돌려줍니다 — 위 10 요청에는 «01 10 00 00 00 02 41 C8» 이 옵니다.
- U32·F32 처럼 두 레지스터가 한 값이면 10 으로 한 번에 씁니다. 06 을 두 번 보내면 두 요청 사이에 장비가 절반만 바뀐 값을 쓸 수 있습니다.
- 장비마다 받는 쓰기 함수가 다릅니다. 루텍 Accura 3300E 는 03·06·16 만 지원합니다. 06 이 없는 장비라면 10 으로 개수 1 을 씁니다.
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 에서는
- 웹 도구 «Modbus 프레임 해석기»: RTU·TCP HEX 를 붙여 넣으면 위 9개 함수의 요청·응답을 칸별로 풀고, 개수가 규격 한도를 넘거나 05 값이 틀리면 알려 줍니다.
- 웹 도구 «Modbus RTU 요청 만들기»: 01~06·0F·10 요청을 국번·주소·개수로 만들고 CRC 까지 붙입니다.
- Modbus Master: 한 칸이면 06(코일은 05), 여러 칸·32/64비트 값이면 10(0F)으로 씁니다. 장비가 06·05 를 받지 않으면 «통신 세부» 에서 한 칸도 여러 칸 쓰기(FC15·16)로 보내게 바꿀 수 있습니다.
작성 2026-10-22