← 로봇 통신 강의 목록으로
🤖
응용
응용 · 선수: 06·07강

08. 모니터링 & 디버깅

06·07편에서 오가는 통신은 눈에 보이지 않는 바이트입니다. "안 되는데 왜 안 되는지 모르겠다"는 순간, 이 바이트를 직접 보고 손으로 해독하는 능력이 디버깅의 전부입니다. 실장비는 HRSS/Caterpillar Modbus Monitor로, PC는 Wireshark로 실제 Modbus/TCP 패킷을 캡처합니다. 그리고 하드웨어 없이도 연습하도록 16진 프레임을 사람이 읽게 풀어 주는 손해독기로 자동 검증합니다.

모니터링디버깅WiresharkModbus MonitorFunction Code16진 해독
소요 시간
약 1.5시간
난이도
📊 중급
선수 조건
🎯 06·07강
결과물
Modbus 패킷의 [Function Code][Data] 구조와 6종 FC의 송수신 포맷을 이해하고, 16진 프레임을 손으로 해독하며 Wireshark/Modbus Monitor로 실제 트래픽을 검증할 수 있습니다.

이 강의에서 배우는 것

  • 1Modbus 패킷이 [Function Code][Data] 구조이며 모니터에 Address·FC·Data가 16진으로 표시됨을 안다
  • 26종 FC(02h·01h·0Fh·04h·03h·10h)의 Master 송신/Slave 응답 포맷을 구분해 손으로 해독한다
  • 3byte 수 규칙(Bit=⌈개수/8⌉ 올림, Word=개수×2)으로 응답 길이를 예측한다
  • 4HRSS Modbus Monitor 절차와 Wireshark(loopback, Decode As Modbus/TCP)를 수행한다

소개

Modbus 패킷은 운반 방식(RTU vs TCP)에 따라 껍데기가 다르지만 알맹이(Slave Address + Function Code + Data)는 동일합니다. 모니터/Wireshark가 보여주는 것이 바로 이 알맹이입니다. TCP는 CRC가 없고(TCP 계층이 무결성 보장), RTU는 끝에 CRC 2바이트가 붙습니다.

핵심 개념

1) Function Code 6종과 byte 규칙

FC의미방향
02hRead Discrete Inputs읽기(Bit)
01hRead Coils읽기(Bit)
0FhWrite Multiple Coils쓰기(Bit)
04hRead Input Registers읽기(Word)
03hRead Holding Registers읽기(Word)
10hWrite Multiple Registers쓰기(Word)
ℹ️

핵심 규칙 두 가지 — ① Bit 응답 byte 수 = ⌈개수/8⌉(올림), ② Word 응답 byte 수 = 개수×2. 읽기는 Master가 "어디서 몇 개"만 보내고 Slave가 데이터를 돌려주며, 쓰기(0Fh·10h)는 Master 송신에 데이터까지 실리고 Slave 응답은 시작주소+개수만 에코합니다.

2) 손계산 예제 3종 (매뉴얼 원문)

text
① 02 01 2C 00 05  → FC02, 시작주소 0x012C=300, 개수 5
② 04 04 00 5A 00 00 → FC04, byte 4(=2개), 값 [0x5A=90, 0]
③ 10 00 C9 00 03 06 00 6F 00 DE 01 4D
   → FC10, 시작주소 0x00C9=201, 개수 3, byte 6, 값 [111,222,333]
   (Slave 응답은 10 00 C9 00 03 — 시작주소+개수만 에코)
⚠️

응답 FC의 최상위 비트가 1(예: 02h→82h)이면 에러 응답이고, 다음 1바이트가 Exception Code입니다(02h 잘못된 주소 / 03h 잘못된 값 / 01h 미지원 기능).

핵심 예제

16진 프레임을 입력하면 Function Code·시작주소·개수·byte수·데이터를 사람이 읽게 푸는 손해독기. 표준 라이브러리만 쓰고 포트가 필요 없어 모니터/Wireshark에서 본 byte를 그대로 검증합니다.

python
decode_frame("02 01 2C 00 05", "request")   # FC=02h, 시작주소 300, 개수 5
decode_frame("04 04 00 5A 00 00", "response")          # byte 4, 값 [90, 0]
decode_frame("10 00 C9 00 03 06 00 6F 00 DE 01 4D", "request")  # 주소 201, 값 [111,222,333]
bash
# 💻 Wireshark 라이브 캡처(선택): Npcap + loopback 어댑터
#  1) python ../../_shared/robot_server_sim.py --port 1502
#  2) python ../../_shared/modbus_master.py --port 1502 read-di 0 8
#  3) 표시 필터 tcp.port == 1502, 비표준 포트는 Decode As → Modbus/TCP
# Query 02 00 00 00 08 / Response 02 01 08 (0x08=주소3만 On → [0,0,0,1,0,0,0,0])

자주 하는 실수

Q. Wireshark에 패킷이 전혀 안 잡혀요(127.0.0.1↔127.0.0.1).

A. 로컬 통신은 물리 랜카드를 거치지 않습니다. 캡처 인터페이스를 Adapter for loopback traffic(Npcap Loopback)로 바꾸세요. 목록에 없으면 Wireshark 재설치 시 Npcap+loopback 옵션을 체크합니다.

Q. Protocol 컬럼이 Modbus/TCP가 아니라 TCP로만 나와요.

A. Wireshark는 502 포트만 Modbus로 자동 해석합니다. 실습은 1502이므로 패킷 우클릭 → Decode As… → 포트 1502를 Modbus/TCP로 지정하세요.

Q. byte 수와 레지스터 개수를 자꾸 헷갈려요.

A. Word는 1개당 2바이트입니다. 레지스터 개수 = byte수 ÷ 2(예: 04 04 ... → byte 4 → 2개). Bit는 반대로 ⌈개수/8⌉로 올림합니다.

정리

  • Modbus 패킷의 알맹이는 [Function Code][Data], 16진수로 표시(HRSS 모니터 최대 200줄)
  • 6종 FC: 읽기 02h/01h/04h/03h, 쓰기 0Fh/10h. 읽기 응답엔 데이터, 쓰기 응답엔 시작주소+개수 에코
  • 길이 규칙: Bit 응답 byte=⌈개수/8⌉, Word 응답 byte=개수×2
  • HRSS Modbus Monitor와 Wireshark(loopback, Decode As Modbus/TCP)로 실제 트래픽을 검증

과제

  1. 세 예제 프레임(02·04·10h)을 손해독기로 풀어 시작주소·개수·값을 확인
  2. 04 04 00 5A 00 00 의 레지스터 개수가 왜 2개인지 byte 규칙으로 설명
  3. Wireshark에서 read-di 8 트래픽을 캡처하고 Response 02 01 08 을 [0,0,0,1,0,0,0,0] 로 해독
예제 코드 / 강의 자료

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

GitHub에서 보기 ↗