← 로봇 통신 강의 목록으로
🤖
MODBUS
MODBUS · 선수: 05강

06. MODBUS SERVER (로봇 = 슬레이브)

05편에서 4종 레지스터를 개별적으로 다뤘다면, 이번 편은 그 레지스터들을 엮어 로봇을 제어합니다. 로봇을 Slave(Server)로 두고 상위 PLC·PC를 Master(Client)로 삼아 "명령 번호 → 파라미터 → 트리거 → 동작 → 응답 확인 → 리셋" 명령 사이클을 돌립니다. 현장에서 PLC가 HIWIN 로봇을 움직이는 실제 방식이며, 32bit 좌표·각도를 Low/High word로 분할하는 법까지 익힙니다.

MODBUS Server명령 사이클Holding Registersplit_word트리거PTP
소요 시간
약 2시간
난이도
📊 중급
선수 조건
🎯 05강
결과물
로봇=Slave 구조에서 명령 실행 5단계(HR201→HR202~→HR200=1→IR 확인→HR200=0)를 수행하고, 32bit 값을 Low/High word로 분할해 PTP/LIN 명령을 보낼 수 있습니다.

이 강의에서 배우는 것

  • 1로봇=Slave Server, PLC=Master Client 구조에서 누가 명령하고 누가 동작하는지 설명한다
  • 2로봇 SO/SI/DI/DO·명령·상태 레지스터가 4종 영역에 어떻게 매핑되는지 안다
  • 3명령 실행 5단계(HR201→HR202~→HR200=1→IR200/IR524 확인→HR200=0)를 수행한다
  • 432bit 좌표·각도를 split_word 로 Low/High word 분할해 넣는다

소개

Master(상위 PLC/PC)가 로봇의 Holding Register에 명령 번호·파라미터·트리거를 써넣으면, Slave(로봇)는 그 값을 보고 실제로 움직이며 진행 상태·현재 위치를 Input Register/Discrete Input에 채워 응답합니다. 로봇은 명령을 받기만 하는 "제어받는 입장"입니다.

핵심 개념

1) 4종 레지스터 매핑 — 감시 vs 명령

영역권한로봇 쪽 의미
Discrete InputRSO(Run/Held/Fault/Ready)·DI 읽기
CoilR/WSI(Start/Hold/Stop/Enable)·DO 읽기/쓰기
Input RegisterR현재 속도·동작 상태·위치 읽기
Holding RegisterR/W속도 설정·명령 번호·파라미터 쓰기

마스터는 R/W 영역(Coil·HR)으로 명령하고, R 영역(DI·IR)으로 상태를 감시합니다. 05편의 권한 차이가 곧 "감시 vs 명령"의 구분입니다.

2) 명령 실행 5단계 (매뉴얼 5.3.3.5)

text
 ① HR[201] ← 명령 번호        (예: 0 = PTP)
 ② HR[202~] ← 파라미터         (모션 타입, 6축 좌표, 속도, Tool/Base)
 ③ HR[200] ← 1                (실행 트리거)
 ④ 로봇 동작 → IR[524] 2(Run)→1(Idle), IR[200]=1(Success)
 ⑤ HR[200] ← 0                (마스터 리셋 → 다음 명령 준비)
⚠️

핵심 규칙: ⑤에서 HR[200]을 0으로 리셋하지 않으면 다음 명령이 실행되지 않습니다.

3) 32bit 값의 Low/High word 분할

python
from word_tools import split_word
split_word(90000)   # → (24464, 1)  Low=90000%65536, High=90000//65536
# 복원: 1×65536 + 24464 = 90000 → ×0.001 = 90.000°
# 음수(-300mm)는 High word가 음수(-5). RobotMaster.write_holding 이 & 0xFFFF 로 자동 인코딩

관절 각도·좌표는 0.001 단위 정수입니다(90.000°→90000). 16bit word는 -32768~32767 까지라 한 word에 못 들어가므로 Low/High 두 word로 나눠 32bit로 표현합니다. 단일 명령은 모션(000~006)·Tool/Base(101~104,201~204)·PR/Home(100·105·200·205) 17종으로 분류됩니다.

핵심 예제

마스터(PLC) 역할로 로봇 슬레이브에 A1 관절을 90°로 PTP 이동시킵니다. 명령 실행 5단계를 그대로 수행합니다.

python
A1_low, A1_high = split_word(90000)        # (24464, 1) = 90.000°
with RobotMaster(host, port) as m:
    params = [0, 0, A1_low, A1_high, 0,0,0,0,0,0,0,0,0,0, 50, 100, 1, 2]
    m.write_holding(201, params)            # ①② HR201~218
    m.write_holding(200, 1)                 # ③ 실행 트리거
    while m.read_input(524,1)[0] != 2: pass          # ④-1 Running 시작 대기
    while not (m.read_input(524,1)[0]==1 and m.read_input(200,1)[0]==1): pass  # ④-2 완료
    m.write_holding(200, 0)                 # ⑤ 트리거 리셋
ℹ️

직전 명령의 Success/Idle 가 남아 있을 수 있어, 먼저 시작(Running=2)을 기다린 뒤 완료(Idle+Success)를 기다리는 2단계 폴링이 안전합니다. IR[300,301]=[24464,1] → 1×65536+24464=90000 → 90.000°.

자주 하는 실수

Q. 트리거를 1로 썼는데 로봇이 안 움직여요.

A. 직전 명령의 HR[200]을 0으로 리셋하지 않은 경우입니다. 절차 ⑤를 빠뜨리면 슬레이브가 ack_wait 상태에서 다음 트리거를 무시합니다(매뉴얼 5.3.3.5 핵심 규칙).

Q. 음수 좌표(X=-300mm)에서 struct.error 'H' format requires 0<=number<=65535.

A. split_word(-300000)=(27680,-5)로 High word가 음수입니다. RobotMaster.write_holding 은 내부에서 값 & 0xFFFF 로 자동 인코딩(-5→65531)하므로 RobotMaster 를 쓰면 추가 처리가 필요 없습니다.

Q. 좌표·각도가 엉뚱한 값으로 들어가요.

A. L/H 워드 순서([Low, High])나 모션 타입(HR202: Joint=0/Cartesian=1) 착오입니다. split_word() 결과를 그 순서대로 넣었는지 확인하세요.

정리

  • 로봇=Slave Server, 상위 PLC/PC=Master Client. 마스터는 R/W로 명령, R로 감시
  • 명령 사이클: HR201=명령번호 → HR202~=파라미터 → HR200=1 → IR200/IR524 확인 → HR200=0 리셋(필수)
  • 16bit를 넘는 좌표·각도는 split_word 로 Low/High 분할, 음수 word는 RobotMaster가 자동 인코딩
  • 단일 명령 17종: 모션(000~006)·T_STOP(005)·Tool/Base·PR/Home

과제

  1. A1=90° PTP 사이클을 완주하고 IR[300,301] 을 디코딩해 90.000° 확인
  2. 절차 ⑤(HR200=0)를 빼면 다음 명령이 잠기는 현상을 재현
  3. X=-300mm 직교 좌표를 split_word 로 인코딩하고 자동 unsigned 변환을 확인
예제 코드 / 강의 자료

전체 강의 자료와 예제 코드(시뮬레이터·과제·정답 포함)는 GitHub에서 자유롭게 받아볼 수 있습니다.

GitHub에서 보기 ↗