05. MODBUS 기초
RS-232가 두 장치를 1:1로 잇는 점대점이었다면, MODBUS는 한 대의 마스터가 여러 슬레이브를 레지스터 단위로 읽고 쓰는 산업 표준 프로토콜입니다. PC만으로 가상 슬레이브를 띄우고, 마스터로 4종 레지스터(Discrete Input·Coil·Input Register·Holding Register)와 Function Code(01~06,15,16)를 직접 읽고/씁니다. 읽기 전용 레지스터에는 쓸 수 없음을 확인합니다.
이 강의에서 배우는 것
- 1MODBUS Master(Client)↔Slave(Server) 요청/응답 구조를 설명한다
- 2Modbus RTU vs TCP의 물리 계층·에러 검증 차이를 비교한다(HIWIN RTU=RS485)
- 34종 레지스터의 비트 폭·읽기/쓰기 권한·값 범위를 구분한다
- 4Function Code(01~06,15,16)가 다루는 레지스터를 매핑한다
소개
MODBUS는 Master(Client)가 요청(Demand)을 보내면 Slave(Server)가 응답(Response)하는 구조입니다. 모든 슬레이브가 명령을 수신하지만 지정된 주소(Address)를 가진 장치만 실행·응답합니다. HIWIN 로봇은 마스터(그리퍼·센서 제어)도, 슬레이브(PLC가 제어)도 될 수 있습니다.
핵심 개념
1) RTU vs TCP
| 구분 | Modbus RTU | Modbus TCP |
|---|---|---|
| 물리 계층 | 시리얼 RS485(HIWIN) | Ethernet |
| 데이터 | Binary 전송 | TCP/IP 패킷에 캡슐화 |
| 에러 검증 | CRC 필수 | TCP 계층이 검증(CRC 생략) |
본 실습은 PC 1대라 Modbus TCP(127.0.0.1)를 씁니다. 데이터 모델(4종 레지스터·Function Code)은 RTU와 완전히 동일해 RS485 RTU에 그대로 적용됩니다.
2) 4종 데이터 레지스터
| 레지스터 | 폭 | 권한 | 범위 |
|---|---|---|---|
| Discrete Input | 1 bit | 읽기 전용(R) | 0~1 |
| Coil | 1 bit | 읽기/쓰기(R/W) | 0~1 |
| Input Register | 16 bit | 읽기 전용(R) | -32768~32767 |
| Holding Register | 16 bit | 읽기/쓰기(R/W) | -32768~32767 |
3) Function Code & 데이터 4부
01=Coil 읽기·02=DI 읽기·03=HR 읽기·04=IR 읽기·05=Coil 단일쓰기·06=HR 단일쓰기·15=Coil 다중쓰기·16=HR 다중쓰기. 규칙: 01/02=비트 읽기, 03/04=word 읽기, 05/06=단일 쓰기, 15/16=다중 쓰기. 읽기 전용(DI·IR)에는 쓰기 코드가 없습니다. 명령은 ① Address ② Function code ③ Data ④ Error check(CRC, TCP는 생략) 4부로 구성됩니다.
핵심 예제
RobotMaster 로 4종을 각각 읽고(02/01/04/03), R/W 권한이 있는 Holding(06)·Coil(05)에 써넣고 되읽어 확인합니다.
with RobotMaster(host, port, unit) as m:
di = m.read_discrete(0, 8) # FC02 Discrete Input
co = m.read_coils(0, 8) # FC01 Coil
ir = m.read_input(524, 1)[0] # FC04 Input Register(동작상태)
hr = m.read_holding(100, 1)[0]# FC03 Holding Register(속도설정)
m.write_holding(100, 50) # FC06 Holding 쓰기
assert m.read_holding(100, 1) == [50]
m.write_coil(300, 1) # FC05 Coil 쓰기(DO1 ON)read_* 는 항상 리스트를 돌려줍니다(단일 값은 [0] 으로 꺼냄). 읽기 전용인 Input Register·Discrete Input 에는 write_input/write_discrete 메서드가 아예 없습니다(읽기 전용 강제). 슬레이브는 별도 터미널에서 robot_server_sim.py --port 1502 로 띄웁니다.
자주 하는 실수
Q. ConnectionError: 슬레이브에 연결 실패.
A. 터미널 A의 슬레이브가 안 떴거나 포트가 다릅니다. robot_server_sim.py --port 1502 가 실행 중인지, 마스터도 --port 1502 로 맞췄는지 확인하세요.
Q. Input Register 에 값을 쓰려는데 메서드가 없어요.
A. 버그가 아니라 설계입니다. Input Register·Discrete Input은 읽기 전용이라 쓰기 Function Code 자체가 없고 RobotMaster 에도 write_input/write_discrete 가 없습니다.
Q. read_holding(100,1) 결과 [50] 이 정수 50 과 다르다고 나와요.
A. read_* 는 항상 리스트입니다. 단일 값은 m.read_holding(100,1)[0] 처럼 [0] 으로 꺼내 비교하세요.
정리
- MODBUS는 Master(요청)↔Slave(응답)이며 명령은 Address·Function code·Data·CRC(TCP 생략) 4부
- RTU=RS485+Binary+CRC 필수, TCP=Ethernet+캡슐화+TCP 검증. HIWIN은 RTU에 RS485
- 4종 레지스터는 비트형(DI=R, Coil=R/W)·word형(IR=R, HR=R/W)으로 나뉘고 권한이 강제된다
- Function Code는 01/02=비트읽기, 03/04=word읽기, 05/06=단일쓰기, 15/16=다중쓰기
과제
- 4종 레지스터를 각각 02/01/04/03 으로 읽고 출력값과 Function Code 대응을 확인
- Holding(06)·Coil(05)에 쓰고 되읽어 ✅ 확인, Input Register 쓰기 메서드가 없음을 확인
- RTU와 TCP 중 CRC가 필요한 쪽과 그 이유를 설명